在python中,为什么0xbin()返回False?

In python, why does 0xbin() return False?

本问题已经有最佳答案,请猛点这里访问。

输入命令0xbin()返回假:

1
2
>>> 0xbin()
False

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


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


如果反汇编代码,您将看到yself的答案,其中提到0xbin()被解释为0xb in ()得到确认:

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


您可以使用Python自己的标记器进行检查!

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

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

1
0xb in ( )

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

(多亏罗马奥达西在评论中建议使用tokenize!)

编辑:为了更全面地解释代码:tokenize函数希望输入的格式有点奇怪,所以io.BytesIO(line).readline是一个将字节序列转换为tokenize可以读取的函数。tokenize然后对其进行标记化,并返回一系列namedtuples;我们获取表示每一个的字符串,并用空格将它们连接在一起。type != 59部分用于忽略将在开头显示的编码说明符。


可以使用ast模块获取表达式的抽象语法树:

1
2
3
4
5
6
7
8
9
10
11
>>> 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=[], ...)提示使用空元组而不是函数调用。