为什么 Python 3 允许“00”作为 0 的文字但不允许“01”作为 1 的文字?
Why does Python 3 allow "00" as a literal for 0 but not allow "01" as a literal for 1?
为什么 Python 3 允许“00”作为 0 的文字但不允许“01”作为 1 的文字?有充分的理由吗?这种矛盾让我很困惑。 (我们正在谈论 Python 3,它故意破坏向后兼容性以实现一致性等目标。)
例如:
>>> from datetime import time
>>> time(16, 00)
datetime.time(16, 0)
>>> time(16, 01)
File "<stdin>", line 1
time(16, 01)
^
SyntaxError: invalid token
>>>
Python2 使用前导零来指定八进制数:
>>> 010
8
为了避免这种(误导?)行为,Python3 需要显式前缀 0b
、0o
、0x
:
>>> 0o10
8
特例("0"+
)
2.4.4. Integer literals
Integer literals are described by the following lexical definitions:
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"
如果您查看语法,很容易看出 0
需要一个特例。我不确定为什么 '+
' 被认为是必要的。是时候浏览开发邮件列表了...
有趣的是,在 Python2 中,不止一个 0
被解析为 octinteger
(尽管最终结果仍然是 0
)
decimalinteger ::= nonzerodigit digit* | "0"
octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+
根据 https://docs.python.org/3/reference/lexical_analysis.html#integer-literals:
Integer literals are described by the following lexical definitions:
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"
There is no limit for the length of integer literals apart from what
can be stored in available memory.
Note that leading zeros in a non-zero decimal number are not allowed.
This is for disambiguation with C-style octal literals, which Python
used before version 3.0.
如此处所述,非零 十进制数中不允许有前导零。 "0"+
作为一种非常特殊的情况是合法的,wasn't present in Python 2:
integer ::= decimalinteger | octinteger | hexinteger | bininteger
decimalinteger ::= nonzerodigit digit* | "0"
octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+
SVN commit r55866 在分词器中实施了 PEP 3127,它禁止使用旧的 0<octal>
数字。然而,奇怪的是,它还添加了这个注释:
/* in any case, allow '0' as a literal */
带有一个特殊的 nonzero
标志,仅当以下数字序列包含非零数字时才会抛出 SyntaxError
。
这很奇怪,因为 PEP 3127 不允许这种情况:
This PEP proposes that the ability to specify an octal number by using a leading zero will be removed from the language in Python 3.0 (and the Python 3.0 preview mode of 2.6), and that a SyntaxError will be raised whenever a leading "0" is immediately followed by another digit.
(强调我的)
因此,允许多个零的事实技术上 违反了 PEP,并且基本上由 Georg Brandl 作为特例实施。他对相应的文档进行了更改,以指出 "0"+
是 decimalinteger
的有效案例(之前已在 octinteger
中涵盖)。
我们可能永远不会确切地知道为什么 Georg 选择让 "0"+
有效 - 它可能永远是 Python 中的一个奇怪的极端情况。
更新 [2015 年 7 月 28 日]:这个问题导致 lively discussion thread on python-ideas in which Georg chimed in:
Steven D'Aprano wrote:
Why was it defined that way? [...] Why would we write 0000 to get zero?
我可以告诉你,但我不得不杀了你。
乔治
稍后,线程生成 this bug report aiming to get rid of this special case. Here, Georg says:
I don't recall the reason for this deliberate change (as seen from the docs change).
I'm unable to come up with a good reason for this change now [...]
因此我们得到了:这种不一致背后的确切原因已经被时间遗忘。
最后,请注意错误报告已被拒绝:对于 Python 3.x.
的其余部分,仅在零整数上将继续接受前导零
为什么 Python 3 允许“00”作为 0 的文字但不允许“01”作为 1 的文字?有充分的理由吗?这种矛盾让我很困惑。 (我们正在谈论 Python 3,它故意破坏向后兼容性以实现一致性等目标。)
例如:
>>> from datetime import time
>>> time(16, 00)
datetime.time(16, 0)
>>> time(16, 01)
File "<stdin>", line 1
time(16, 01)
^
SyntaxError: invalid token
>>>
Python2 使用前导零来指定八进制数:
>>> 010
8
为了避免这种(误导?)行为,Python3 需要显式前缀 0b
、0o
、0x
:
>>> 0o10
8
特例("0"+
)
2.4.4. Integer literals
Integer literals are described by the following lexical definitions: 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"
如果您查看语法,很容易看出 0
需要一个特例。我不确定为什么 '+
' 被认为是必要的。是时候浏览开发邮件列表了...
有趣的是,在 Python2 中,不止一个 0
被解析为 octinteger
(尽管最终结果仍然是 0
)
decimalinteger ::= nonzerodigit digit* | "0" octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+
根据 https://docs.python.org/3/reference/lexical_analysis.html#integer-literals:
Integer literals are described by the following lexical definitions:
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"
There is no limit for the length of integer literals apart from what can be stored in available memory.
Note that leading zeros in a non-zero decimal number are not allowed. This is for disambiguation with C-style octal literals, which Python used before version 3.0.
如此处所述,非零 十进制数中不允许有前导零。 "0"+
作为一种非常特殊的情况是合法的,wasn't present in Python 2:
integer ::= decimalinteger | octinteger | hexinteger | bininteger
decimalinteger ::= nonzerodigit digit* | "0"
octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+
SVN commit r55866 在分词器中实施了 PEP 3127,它禁止使用旧的 0<octal>
数字。然而,奇怪的是,它还添加了这个注释:
/* in any case, allow '0' as a literal */
带有一个特殊的 nonzero
标志,仅当以下数字序列包含非零数字时才会抛出 SyntaxError
。
这很奇怪,因为 PEP 3127 不允许这种情况:
This PEP proposes that the ability to specify an octal number by using a leading zero will be removed from the language in Python 3.0 (and the Python 3.0 preview mode of 2.6), and that a SyntaxError will be raised whenever a leading "0" is immediately followed by another digit.
(强调我的)
因此,允许多个零的事实技术上 违反了 PEP,并且基本上由 Georg Brandl 作为特例实施。他对相应的文档进行了更改,以指出 "0"+
是 decimalinteger
的有效案例(之前已在 octinteger
中涵盖)。
我们可能永远不会确切地知道为什么 Georg 选择让 "0"+
有效 - 它可能永远是 Python 中的一个奇怪的极端情况。
更新 [2015 年 7 月 28 日]:这个问题导致 lively discussion thread on python-ideas in which Georg chimed in:
Steven D'Aprano wrote:
Why was it defined that way? [...] Why would we write 0000 to get zero?
我可以告诉你,但我不得不杀了你。
乔治
稍后,线程生成 this bug report aiming to get rid of this special case. Here, Georg says:
I don't recall the reason for this deliberate change (as seen from the docs change).
I'm unable to come up with a good reason for this change now [...]
因此我们得到了:这种不一致背后的确切原因已经被时间遗忘。
最后,请注意错误报告已被拒绝:对于 Python 3.x.
的其余部分,仅在零整数上将继续接受前导零