【问题标题】:In python, why does 0xbin() return False? [duplicate]在 python 中,为什么 0xbin() 返回 False? [复制]
【发布时间】:2019-01-02 09:45:14
【问题描述】:

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

>>> 0xbin()
False

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

【问题讨论】:

  • 需要参数! 0xbin(013,37)
  • @nneonneo,如果你想获得True,你可以尝试0xbin(11,) 使用一个参数
  • 0xbin(013,37) 也会给你 True ;)(在 Python 2.7 中)
  • 比较和对比0xband()Tokenizer 是贪婪的,并以 0xba 作为令牌。
  • @投票重新开放的人:请解释为什么这不是骗局。如果你说服我,我会重新打开它。

标签: python


【解决方案1】:

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

【讨论】:

  • 显然“in”、“is”等不需要空格?我第一次遇到这种情况,但这是有道理的,因为“
  • 显然是的。 Python Reference 表示只有“如果它们的连接可以被解释为不同的标记”,才需要标记之间的空格。但我只在Code Golf见过这样的代码。
  • @MattS 这就是为什么有效的 python 标识符(和许多其他语言)只接受标识符的第一个字母的字母或下划线,然后允许数字。由于完全支持 Unicode,实际实现相当复杂,但标识符的纯 ASCII 正则表达式为:r'[_a-zA-Z][_a-zA-Z0-9]*'
  • @Aaron: [_[:alpha:]][_[:alnum:]]* 在允许(Unicode)字符类的正则表达式语言中,即。 e.不是 Python 的。 ;-]
  • 哇,我以为这种解析只能在 Fortran 和 BASIC 中完成。我不敢相信现代语言能做到。
【解决方案2】:

如果你反汇编代码,你会看到Yself's answer,其中提到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

【讨论】:

  • list(tokenize.tokenize(io.BytesIO(b"0xbin()").readline)) 可能更合适
【解决方案3】:

可以使用 Python 自带的分词器来检查!

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 建议在 cmets 中使用 tokenize!)

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

【讨论】:

  • 这是迄今为止最好的答案,“dis”和“ast”的答案掩盖了不常见符号背后发生的事情,这在普通 python 中清楚地表明了这一点。
【解决方案4】:

可以使用AST模块获取表达式的abstract syntax tree

>>> 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())
                                         ]
                            ))])'

请参阅 abstract grammar 了解如何解释表达式,但 tl;dr:Num(n=11)0xb 部分,Tuple(elts=[], ...) 提示指向空元组而不是函数调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-11
    • 2012-09-29
    • 2015-06-22
    • 2021-11-10
    • 2015-02-23
    相关资源
    最近更新 更多