问题描述
当查看Python中的str
和bytes
类型时,发现它们非常相似。唯一的区别是。它们的属性是:
>>> set(dir(bytes)) - set(dir(str))
{'hex','fromhex','decode'}
>>> set(dir(str)) - set(dir(bytes))
{'isidentifier','encode','isdecimal','isnumeric','casefold','format','isprintable','format_map'}
检查Python documentation时,我发现这些差异与其与抽象基类collections.abc.ByteString
的关系不相关。但是,bytes
被视为子类,而str
不是:
>>> issubclass(bytes,collections.abc.ByteString)
True
>>> issubclass(str,collections.abc.ByteString)
False
虽然观察到的行为对于识别这些类型很有用,但我不明白为什么Python会这样做。在我对Python的鸭子类型概念的理解中,str
和bytes
都应该被视为子类,只要它们具有相关的属性即可。
解决方法
str
不是一个字节字符串。 ByteString
的含义不包含在其方法中,并且str
不符合ByteString
的含义。 (ABC主要作为捆绑bytes
和bytearray
进行isinstance
检查的一种方式,因此在其文档字符串中“这将字节和字节数组统一。”)
您可能想知道为什么issubclass
不会根据其方法自动将str
视为ByteString
的子类。除非ABC特别实现__subclasshook__
来检查方法,否则issubclass
不会基于任何特定方法的存在而自动将类视为ABC的子类。 bytes
和bytearray
是ByteString
的子类,因为它们专门register
被作为子类。
从实际的角度来看,str
和bytes
不能互相替代,因此没有任何用途可以使它们成为Iterable
或Hashable
或Sized
...
如果要互换使用它们,则程序中可能存在错误。