有没有一种pythonics方法来区分像"tuple and list"这样的序列对象和像"bytes and str"这样的序列对象



我有一个这样的函数

def print_stuff(items):
if isinstance(items, (str, bytes)):
items = (items,)
for item in items:
print (item)

可以按如下方式调用:

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,例如

  • 列表
  • numpy.array
  • 一些用户定义的向量类等

但不是:

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

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

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中只有一种字符串类型,因此最Pythonic的解决方案确实是使用isinstance(x, str)
  • 可以使用
  • ABCcollections.abc.ByteString来区分字节序列类型(如bytesbytearray)。

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

你的魔法叫做types.StringTypes.它不是抽象的基类,但它是我们拥有的最好的。

从 https://docs.python.org/2/library/types.html#types.StringTypes(强调我的):

包含StringTypeUnicodeType的序列,用于促进 更轻松地检查任何字符串对象。使用这个更便携 而不是使用在其他地方构造的两种字符串类型的序列 因为它只包含UnicodeType如果它是在运行中构建的 蟒蛇的版本。例如:isinstance(s, types.StringTypes).

版本 2.2 中的新功能。

最新更新