关于python 3.x:是否有一种pythonics方法可以将Sequences对象(如“tuple和list”)与Sequence对象(如“bytes和str”)区分开来

is there a pythonics way to distinguish Sequences objects like “tuple and list” from Sequence objects like “bytes and str”

我有这样的功能

1
2
3
4
5
def print_stuff(items):
    if isinstance(items, (str, bytes)):
        items = (items,)
    for item in items:
        print (item)

可称为:

1
2
3
4
5
6
In [37]: print_stuff(('a', 'b'))
a
b

In [38]: print_stuff('a')
a

我不喜欢做isinstance (items, (str, bytes)),我更喜欢做isinstance(item, (collections.abc.MAGIC))

其中magic是可以包含其他序列对象的所有序列对象的ABC,例如

  • 元组
  • 列表
  • 编号数组
  • 一些用户定义的向量类等

但不是:

  • STR
  • 字节
  • 一些用户定义的用于UTF-16等的str类

恐怕这是不可能的,因为tuplestr有相同的7个ABC:(

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
In [49]: [v for k, v in vars(collections.abc).items()
    ...:                                   if inspect.isclass(v) and issubclass(tuple, v) ]
Out[49]:
[collections.abc.Hashable,
 collections.abc.Iterable,
 collections.abc.Reversible,
 collections.abc.Sized,
 collections.abc.Container,
 collections.abc.Collection,
 collections.abc.Sequence]

In [50]: [v for k, v in vars(collections.abc).items()
    ...:                                   if inspect.isclass(v) and issubclass(list, v) ]
Out[50]:
[collections.abc.Iterable,
 collections.abc.Reversible,
 collections.abc.Sized,
 collections.abc.Container,
 collections.abc.Collection,
 collections.abc.Sequence,
 collections.abc.MutableSequence]

In [51]: [v for k, v in vars(collections.abc).items()
    ...:                                   if inspect.isclass(v) and issubclass(str, v) ]
Out[51]:
[collections.abc.Hashable,
 collections.abc.Iterable,
 collections.abc.Reversible,
 collections.abc.Sized,
 collections.abc.Container,
 collections.abc.Collection,
 collections.abc.Sequence]


问得好。

  • 目前还没有abc将字符串与元组或其他不变序列区分开来;因为在python 3中只有一种字符串类型,所以最简单的解决方案实际上是使用isinstance(x, str)
  • 字节序列类型,如bytesbytearray可以用collections.abc.ByteStringabc来区分。

当然,你也可以定义你自己的ABC,包括strByteString,甚至给它一个__subclasshook__,检查类的方法,比如capitalize


你的魔法被称为江户记1〔8〕。它不是抽象的基类,但它是我们所拥有的最好的。

来自https://docs.python.org/2/library/types.html types.stringtypes(emphasis mine):

A sequence containing StringType and UnicodeType used to facilitate
easier checking for any string object. Using this is more portable
than using a sequence of the two string types constructed elsewhere
since it only contains UnicodeType if it has been built in the running
version of Python. For example: isinstance(s, types.StringTypes).

New in version 2.2.