访问文字属性适用于所有类型,但不适用于`int`;为什么?

时间:2015-10-10 12:55:24

标签: python python-2.7 python-3.x language-lawyer

我已经读过python中的所有内容都是一个对象,因此我开始尝试使用不同类型并在其上调用 __str__ - 起初我感到非常兴奋,但是然后我感到困惑。

>>> "hello world".__str__()
'hello world'
>>> [].__str__()
'[]'
>>> 3.14.__str__()
'3.14'
>>> 3..__str__()
'3.0'
>>> 123.__str__()
  File "<stdin>", line 1
    123.__str__()
              ^
SyntaxError: invalid syntax
  • 为什么something.__str__()适用于int以外的“所有”?
  • 123不是int类型的对象吗?

4 个答案:

答案 0 :(得分:89)

你需要parens:

(4).__str__()

问题是词法分析员认为“4”将是一个浮点数。

此外,这也有效:

x = 4
x.__str__()

答案 1 :(得分:48)

所以你认为你可以跳舞浮点数?

1233.14一样对象,“问题”在于语言的语法规则;解析器认为我们要定义一个 float - 而不是带有尾随方法调用的 int

如果我们将数字括在括号中,我们将得到预期的行为,如下所示。

>>> (123).__str__()
'123'

或者,如果我们只是在 123 之后添加一些空格:

>>> 123 .__str__()
'123'


它对123.__str__()无效的原因是 123 后面的 dot 被解释为小数点部分声明的浮点

>>> 123.__str__()
  File "", line 1
    123.__str__()
              ^
SyntaxError: invalid syntax

解析器尝试将__str__()解释为数字序列,但显然失败了 - 我们得到一个 SyntaxError ,基本上说解析器偶然发现了一些它没想到的东西。 / p>


精化

查看123.__str__()时,python解析器可以使用 3 字符,并将这些 3 字符解释为整数,< strong>或它可以使用 4 字符并将其解释为浮点开始

123.__str__()
^^^ - int
123.__str__()
^^^^- start of floating-point

就像一个小孩子想要在他们的盘子上尽可能多的蛋糕一样,解析器是贪婪的,并且想要尽可能多地吞下 - 即使这并不总是最好的想法 - 如选择后者(“更好”)的替代方案。

当它后来意识到__str__()不能被解释为浮点小数时,已经太晚了; 的SyntaxError

  

注意

 123 .__str__() # works fine
     

在上面的代码段中,123 (请注意空格)必须解释为整数,因为 number 不能包含空格。这意味着它在语义上等同于(123).__str__()

  

注意

 123..__str__() # works fine
     

上述方法也有效,因为数字最多只能包含一个小数点,这意味着它等同于(123.).__str__()


language-lawyers

本节包含相关文字的词汇定义。

<子>的 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"

答案 2 :(得分:42)

4

之后添加空格
4 .__str__()

否则,词法分析器会将此表达式拆分为标记"4.""__str__""("")",即第一个标记被解释为浮点数。词法分析器总是尝试构建最长的令牌。

答案 3 :(得分:6)

实际上(为了增加不可读性......):

4..hex()

也有效。它给出了'0x1.0000000000000p+2' - 但它当然是浮动的......