如何使用Python 3的标准库测试不像字符串的序列

DGr*_*ady 7 python abstract-class types interface python-3.x

一段时间以来,Python已经有了抽象基类(PEP 3119中的 orignally ),特别是对于容器类型,可以更容易地编写跨越自定义类型的代码.例如,

from collections.abc import Sequence, Set

if isinstance(x, Sequence):
    # Handle lists, tuples, or custom objects that behave like lists
elif isinstance(x, Set):
    # Handle anything that behaves like a set
Run Code Online (Sandbox Code Playgroud)

一个多数民众赞成我绊倒了几次"陷阱"的是str,bytesbytearray都被认为是SequenceS,除了更为明显列表类似的对象:

from collections.abc import ByteString, Sequence

s = 'hello'
b = b'hello'
ba = bytearray(b'hello')
lst = [0, 1, 2]
t = (0, 1, 2)

islistlike = lambda x: isinstance(x, Sequence)

list(map(islistlike, [s, b, ba, lst, t])) # -> [True, True, True, True, True]
Run Code Online (Sandbox Code Playgroud)

这当然是有道理的:通常这三种类型的行为就像列表或字符元组(或字节).但是,这似乎是一个非常常见的用例,这个对象x既像列表一样又不像字符串一样?修复很简单:

islistlike = lambda x: isinstance(x, Sequence) and not isinstance(x, (str, ByteString))

list(map(islistlike, [s, b, ba, lst, t])) # -> [False, False, False, True, True]
Run Code Online (Sandbox Code Playgroud)

但这似乎是一个足够普遍的模式,我想知道我是否遗漏了标准库中的某些内容.

  • abc在Python的标准库中有没有islistlike = lambda x: isinstance(x, abc)像上面最后一个例子那样的行为?
  • 有什么设计讨论围绕Sequencevs类似字符串的容器吗?(我在标准库文档或PEP 3119中找不到与此相关的任何内容.)

Eth*_*man 2

不,标准库中没有任何内容可以轻松地区分strandbytes类序列与其他序列类型。如果这在您的代码库中很常见,那么您可能想要推出自己的代码库。