python-3.x – 是否有一种pythonics方法来区分Sequences对象,如“tuple和list”,来自Sequence对象,如“bytes和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
>字节
>一些用户为UTF-16定义的str类等

我担心这是不可能的,因为元组和str具有相同的7个ABCs 🙁

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).
>可以使用collections.abc.ByteString ABC区分字节序列类型,如bytes和bytearray.

当然,您也可以定义自己的ABC,其中包括str和ByteString,或者甚至给它一个__subclasshook__来检查类的方法,例如大写.

点赞