In python, why does 0xbin() return False?
输入命令0xbin()返回假:
为什么会这样?这个语法应该没有任何意义。函数不能以0开头,十六进制中没有"i"和"n",bin函数必须有一些参数。
- 它需要争论!0xbin(013,37)。
- @如果你想得到True,你可以用一个单一的论点来尝试0xbin(11,)。
- 0xbin(013,37)也会给出正确的答案;)(在python 2.7中)
- 这仅仅是因为lexer和parser的实现者只关心通过良好格式化的代码获得所需的行为。将0xb和in并列应视为无效的令牌。
- 与0xband()比较对比。tokenizer贪婪,把0xba作为tokenizer。
- @投票重新开放的人:请解释为什么这不是一个骗局。如果你说服我,我会重新打开它。
- @Kevin可能是dupe的目标,"为什么有时候代币之间不需要空格?"这个问题就像"代币是什么?"(我可以重新开放自己,但既然我回答了,而且有很多选票,我就不会这么做了,以防它被视为COI)
python似乎把0xbin()解释为0xb in (),意思是空元组中有11个。答案是否定的,因此False。
- 所以很明显"in"、"is"等不需要空间?我第一次遇到这个问题,但它是有意义的,因为"<"和"=="也不需要它们。
- 显然是的。python引用说,只有当标记之间的连接可以解释为不同的标记时,才需要标记之间的空白。但我只在"代码高尔夫"中见过这样的代码。
- @matts这就是为什么有效的python标识符(和许多其他语言)只接受字母或下划线作为标识符的第一个字母,然后允许数字。由于完全支持Unicode,实际实现相当复杂,但标识符的纯ASCII regex是:r'[_a-zA-Z][_a-zA-Z0-9]*'。
- @Aaron:[_[:alpha:]][_[:alnum:]]*,使用允许(Unicode)字符类的正则表达式语言,即不使用Python的。;-]
- 哇,我以为这种解析只在Fortran和Basic中完成。我不敢相信现代语言能做到这一点。
- C语言家族中对"预处理数"的特殊定义的原因之一是为了防止出现这种情况;在这些语言中,0xbin将被视为单个标记,即使它不能被解释为有效的数字文字。
- @davidfoerster您可以使用regex,而不是内置的re。它提供了相同的API,但增加了许多功能,包括匹配的Unicode属性等。我希望在一些版本中,将取代标准的re模块…(我相信作者也有这个希望,因此两者之间的高度兼容)。
- @巴尔马Python很老。
- @Ronjohn我已经编程40年了,Python还不到30年。据我所知,这是一个年轻的鞭打者。
- @Barmar:python希望保持ll(1)语言。这实际上与这个示例没有任何关系,但是它说明了他们对"哑"解析器的持续需求(也提供了一些解释方式)。tl;dr:他们不想让python像perl一样结束。
如果反汇编代码,您将看到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 |
- list(tokenize.tokenize(io.BytesIO(b"0xbin()").readline))可能更合适
您可以使用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)) |
这将打印字符串中的标记,用空格分隔。在这种情况下,结果将是:
。
换句话说,它返回false,因为数字11(0xb不在空元组(()中)。
(多亏罗马奥达西在评论中建议使用tokenize!)
编辑:为了更全面地解释代码:tokenize函数希望输入的格式有点奇怪,所以io.BytesIO(line).readline是一个将字节序列转换为tokenize可以读取的函数。tokenize然后对其进行标记化,并返回一系列namedtuples;我们获取表示每一个的字符串,并用空格将它们连接在一起。type != 59部分用于忽略将在开头显示的编码说明符。
- 这是目前最好的答案,"dis"和"ast"的答案掩盖了不常见符号背后所发生的事情,这在普通的Python中清楚地显示了这一点。
可以使用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=[], ...)提示使用空元组而不是函数调用。