在 Python 中,为什么 0xbin() 返回 false ?

输入命令0xbin()将返回FALSE:

>>> 0xbin()
False

为什么会这样?这个语法应该没有任何意义。函数不能以0开头,十六进制中没有“ I ”和“ n ”,并且bin函数必须有一些参数。

8351 次浏览

Python似乎将0xbin()解释为0xb in (),意思是空元组中的11。 答案是否定的,因此False

如果您对代码进行反汇编,您将看到你自己的回答(其中提到0xbin()被解释为0xb in ())得到确认:

>>> import dis
>>> dis.dis('0xbin()')
1           0 LOAD_CONST               0 (11)
2 BUILD_TUPLE              0
4 COMPARE_OP               6 (in)
6 RETURN_VALUE

可以使用“阿斯特 ”模块获取表达式的抽象语法树

>>> import ast
>>> m = ast.parse('0xbin()')
>>> ast.dump(m)
'Module(
body=[Expr(
value=Compare(left=Num(n=11),
ops=[In()],
comparators=[Tuple(elts=[],
ctx=Load())
]
))])'

有关如何解释表达式的信息,请参阅抽象语法,但TL;DR:Num(n=11)0xb部分,并且Tuple(elts=[], ...)提示指向空元组而不是函数调用。

您可以使用Python自带的Tokenizer进行检查。

import tokenize
import io
line = b'0xbin()'
print(' '.join(token.string for token in tokenize.tokenize(io.BytesIO(line).readline) if token.type!=59))

这将打印字符串中的标记,以空格分隔。在这种情况下,结果将是:

0xb in ( )

换句话说,它返回false,因为数字11(0xb)不在空元组(())中。

(感谢Roman Odaisky在评论中建议使用tokenize!)

编辑:为了更彻底地解释代码:tokenize函数期望输入的格式有点奇怪,因此io.BytesIO(line).readline是一个将字节序列转换为ABC_0_可以读取的内容的函数。然后,tokenize将其标记化,并返回一系列namedtuple。我们用字符串表示每一个,并用空格将它们连接在一起。type != 59部分用于忽略编码说明符,否则该说明符将出现在开头。