所以你认为你可以跳舞浮点数?
123 和3.14 一样是一个对象,“问题”在于语言的语法规则;解析器认为我们将要定义一个 float——而不是一个带有尾随方法调用的 int。
如果我们将数字括在括号中,我们将得到预期的行为,如下所示。
>>> (123).__str__()
'123'
或者如果我们只是在123之后添加一些空格:
>>> 123 .__str__()
'123'
它不适用于123.__str__() 的原因是123 后面的点 被解释为小数点一些部分声明的浮点。
>>> 123.__str__()
File "", line 1
123.__str__()
^
SyntaxError: invalid syntax
解析器尝试将__str__() 解释为数字序列,但显然失败了——我们得到一个SyntaxError,基本上说解析器偶然发现了一些它没有预料到的东西。
细化
当查看123.__str__() 时,python 解析器可以使用 3 个字符并将这些 3 个字符解释为一个 整数,或者它可以使用 4 个字符并将这些字符解释为 浮点的开始。
123.__str__()
^^^ - int
123.__str__()
^^^^- start of floating-point
就像小孩子想要盘子里尽可能多的蛋糕一样,解析器也很贪婪,想要一次吞下尽可能多的东西——即使这并不总是最好的想法——因为选择后一种(“更好”)替代方案。
当它后来意识到__str__() 决不能被解释为浮点的小数时,已经太迟了; 语法错误。
注意
123 .__str__() # works fine
在上面的 sn-p 中,123 (注意空格)必须被解释为 整数,因为没有 数字 可以包含空格。这意味着它在语义上等同于(123).__str__()。
注意
123..__str__() # works fine
上述方法也有效,因为一个数字最多可以包含一个小数点,这意味着它等价于(123.).__str__()。
对于语言律师
本节包含相关文字的词法定义。
Lexical analysis - 2.4.5 Floating point literals
floatnumber ::= pointfloat | exponentfloat
pointfloat ::= [intpart] fraction | intpart "."
exponentfloat ::= (intpart | pointfloat) exponent
intpart ::= digit+
fraction ::= "." digit+
exponent ::= ("e" | "E") ["+" | "-"] digit+
Lexical analysis - 2.4.4 Integer literals
integer ::= decimalinteger | octinteger | hexinteger | bininteger
decimalinteger ::= nonzerodigit digit* | "0"+
nonzerodigit ::= "1"..."9"
digit ::= "0"..."9"
octinteger ::= "0" ("o" | "O") octdigit+
hexinteger ::= "0" ("x" | "X") hexdigit+
bininteger ::= "0" ("b" | "B") bindigit+
octdigit ::= "0"..."7"
hexdigit ::= digit | "a"..."f" | "A"..."F"
bindigit ::= "0" | "1"