为什么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,它故意破坏向后兼容性以实现一致性等目标。)
Why does Python 3 allow "00" as a literal for 0 but not allow "01" as a literal for 1? Is there a good reason? This inconsistency baffles me. (And we're talking about Python 3, which purposely broke backward compatibility in order to achieve goals like consistency.)
例如:
>>> from datetime import time
>>> time(16, 00)
datetime.time(16, 0)
>>> time(16, 01)
File "<stdin>", line 1
time(16, 01)
^
SyntaxError: invalid token
>>>
推荐答案
每 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.
请注意,不允许使用非零十进制数的前导零。
这是用于消除C风格八进制文字的消歧,在3.0版之前使用Python
。
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.
As这里注意到,不允许在非零十进制数字中前导零。 0+
作为一个非常特殊的案例是合法的,在Python 2中不存在:
As noted here, leading zeros in a non-zero decimal number are not allowed. "0"+
is legal as a very special case, which 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 在tokenizer中实现了PEP 3127,禁止旧版本 0< octal>
数字。然而,奇怪的是,它还添加了这个注释:
SVN commit r55866 implemented PEP 3127 in the tokenizer, which forbids the old 0<octal>
numbers. However, curiously, it also adds this note:
/* in any case, allow '0' as a literal */
带有特殊的非零
标志,只会抛出一个 SyntaxError
如果以下数字序列包含非零数字。
with a special nonzero
flag that only throws a SyntaxError
if the following sequence of digits contains a nonzero digit.
这是奇怪的,因为 PEP 3127 不允许这种情况:
This is odd because PEP 3127 does not allow this case:
这个PEP建议通过使用前导零来指定八进制数的能力将从Python 3.0中的语言(以及2.6的Python 3.0预览模式)中删除,并且 a只要前导0紧跟另一个数字,就会引发SyntaxError。
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
)。
So, the fact that multiple zeros are allowed is technically violating the PEP, and was basically implemented as a special case by Georg Brandl. He made the corresponding documentation change to note that "0"+
was a valid case for decimalinteger
(previously that had been covered under octinteger
).
我们可能永远不会知道完全为什么Georg选择了使0+
有效 - 在Python中它可能永远是一个奇怪的角落。
We'll probably never know exactly why Georg chose to make "0"+
valid - it may forever remain an odd corner case in Python.
更新 [2015年7月28日]:这个问题导致生动的讨论主题,其中 Georg chimed in :
UPDATE [28 Jul 2015]: This question led to a lively discussion thread on python-ideas in which Georg chimed in:
Steven D'Aprano写道:
Steven D'Aprano wrote:
为什么这样定义? [...]为什么我们写0000才能获得零?
Why was it defined that way? [...] Why would we write 0000 to get zero?
我可以告诉你,但是我必须杀了你。
I could tell you, but then I'd have to kill you.
Georg
稍后,该线程产生了此错误报告旨在摆脱这种特殊情况。在这里,乔治说:
Later on, the thread spawned 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 [...]
因此我们拥有它:这种不一致背后的确切原因是时间丢失。
and thus we have it: the precise reason behind this inconsistency is lost to time.
最后,请注意错误报告被拒绝:对于Python 3.x的其余部分,前导零将继续只接受零整数。
Finally, note that the bug report was rejected: leading zeros will continue to be accepted only on zero integers for the rest of Python 3.x.
这篇关于为什么Python 3允许“00”。作为0的文字但不允许“01”作为1的字面值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!