为什么内置函数`any(b'\ x00')`在python2和python3之间的行为不同?

时间:2018-12-04 13:19:51

标签: python

以下示例在Python 2.x中返回True,而在Python 3.x中返回False

 python -c "print(any(b'\x00'))"

我找不到任何区别的解释。 bool(b'\x00')在Python 2.x和Python 3.x中都返回True。我希望值为true,因为字节序列包含一个元素,该元素的值为True。

我错过了语言说明/文档的哪一部分?

2 个答案:

答案 0 :(得分:4)

在Python 2.x上,当迭代诸如b'\x00\x00\x00'之类的字节字符串时,迭代器将其组件作为子字符串生成:

>>> list(iter(b'\x00\x00\x00'))
['\x00', '\x00', '\x00']
>>> list(b'\x00\x00\x00')
['\x00', '\x00', '\x00']

这是因为字节字符串只是Python 2中的字符串,因此表现出相同的行为。

OTOH,如果我们使用python 3,则字节字符串会以int s的形式输出其内容:

>>> list(iter(b'\x00\x00\x00'))
[0, 0, 0]
>>> list(b'\x00\x00\x00')
[0, 0, 0]

从这种差异中,其他一切都很清楚:正如我们已经注意到的,bool(b'\x00')True,而bool(0)False

在一个元素字符串上进行迭代时也是如此:list(b'\x00')在Py2中提供['\x00'],在Py3中提供[0][bool(i) for i in b'\x00']在Py2中提供[True] vs 。[False]在Py3中,因此有所不同。

请注意

any([bool(i) for i in b'\x00'])
any([i for i in b'\x00'])
any(b'\x00')

在语义上是相同的:遍历给定的对象,获取每个项目的真实值,然后返回True

TLDR:Python 2中为b'\x00'[0] == b'\x00',Python 3中为0

答案 1 :(得分:2)

在Python2中,b'\ x00'为str类型。在Python3中,b'\ x00'是\ type bytes

在Python3中

  

虽然字节文字和表示形式基于ASCII文本,但字节对象实际上的行为就像不可变的整数序列[...]

https://docs.python.org/3/library/stdtypes.html#binaryseq

因此,在Python3中,您的字节字符串由整数0(即False)组成。在Python2中,它由str“字符”(非空)组成,因此由True组成。