파이썬 3은 왜 "00"을 0의 리터럴로 허용하지만 "01"을 1의 리터럴로 허용하지 않습니까?


111

왜 파이썬 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
>>>

42
지금 제거 할 수 없습니다. 그렇지 않으면이 질문과의 하위 호환성이 깨집니다!
John La Rooy 2015

답변:


103

https://docs.python.org/3/reference/lexical_analysis.html#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"

사용 가능한 메모리에 저장할 수있는 것 외에는 정수 리터럴의 길이에 대한 제한이 없습니다.

0이 아닌 10 진수의 선행 0은 허용되지 않습니다. 이것은 파이썬이 3.0 이전에 사용했던 C 스타일 8 진 리터럴과의 명확성을위한 것입니다.

여기에서 언급했듯이 0이 아닌 10 진수의 선행 0은 허용되지 않습니다. 파이썬 2에는 없었던"0"+ 매우 특별한 경우로 합법적입니다 .

integer        ::=  decimalinteger | octinteger | hexinteger | bininteger
decimalinteger ::=  nonzerodigit digit* | "0"
octinteger     ::=  "0" ("o" | "O") octdigit+ | "0" octdigit+

SVN commit r55866 은 tokenizer에서 PEP 3127을 구현하여 이전 0<octal>번호 를 금지합니다 . 그러나 흥미롭게도 다음과 같은 메모도 추가합니다.

/* in any case, allow '0' as a literal */

다음 숫자 시퀀스에 0이 아닌 숫자가 포함 된 경우 nonzero에만 a를 던지는 특수 플래그가 SyntaxError있습니다.

PEP 3127 이이 경우를 허용하지 않기 때문에 이것은 이상합니다 .

이 PEP는 선행 0을 사용하여 8 진수를 지정하는 기능이 Python 3.0 (및 Python 3.0 미리보기 모드 2.6)의 언어에서 제거되고 선행 "0"이 올 때마다 SyntaxError가 발생한다고 제안합니다. 바로 뒤에 다른 숫자가옵니다 .

(강조 내)

따라서 여러 개의 0이 허용된다는 사실은 기술적 으로 PEP를 위반하는 것이며 기본적으로 Georg Brandl에 의해 특수 사례로 구현되었습니다. 그는 해당 문서를 변경하여 (이전에는에서 다루었던) "0"+유효한 사례 임을 기록했습니다 .decimalintegeroctinteger

우리는 Georg가 왜 유효화를 선택 했는지 정확히 알지 못할 것입니다 "0"+. 파이썬에서 영원히 이상한 경우로 남아있을 수 있습니다.


업데이트 [2015 년 7 월 28 일] :이 질문은 Georg가 다음 같이 했던 파이썬 아이디어에 대한 활발한 토론 스레드로 이어졌습니다 .

Steven D' Aprano는 다음과 같이 썼습니다.

왜 그렇게 정의 되었습니까? [...] 왜 우리는 0을 얻기 위해 0000을 쓰겠습니까?

말해 줄 수는 있지만 그럼 죽여야 해요

게오르그

나중에 스레드 는이 특별한 경우를 제거하기 위해이 버그 보고서를 생성 했습니다 . 여기 Georg는 다음과 같이 말합니다 .

이 의도적 인 변경의 이유를 기억하지 못합니다 (문서 변경에서 볼 수 있음).

나는 지금이 변화에 대한 좋은 이유를 생각 해낼 수 없다 ...]

따라서 우리는 그것을 가지고 있습니다.이 불일치의 정확한 이유는 시간이 지남에 따라 사라집니다.

마지막으로, 버그 보고서가 거부되었습니다. 나머지 Python 3.x에서는 0 정수에서만 선행 0이 계속 허용됩니다.


6
왜 "우리는 Georg가 왜 ...을 선택했는지 정확히 알지 못할 것입니다."라고 말합니까? 그를 아는 사람이이 스레드를보고 그에 대해 알리면 그가 올 수 있습니다. (당신이 알지 못한다면 그는 자신의 과거 파이썬 작업을 논의하기 위해 거부 영원히, 또는 이와 유사한 상황)
바다 코끼리

1
나는 그들이 왜 두 번째 Python 2 octinteger사례를 만들지 않았는지 이해하지 못합니다 "0" octdigit*. 0C / C ++의 8 진수 리터럴입니다.
Random832

1
사실 영어는 이와 관련하여 약간 모호합니다. "다른"이라는 단어는 "하나 더"를 의미하거나 "다른 사람"을 의미 할 수 있습니다. PEP 3127의 굵은 따옴표에 대한 유효한 영어 해석 중 하나는 "앞의 '0'다음에 '0'이 아닌 숫자가 바로 뒤에 올 때마다 SyntaxError가 발생합니다."라는 의미입니다. 이것이 실제로 의도 한 것인지 잘 모르겠습니다 ( 비록 그 해석이 실제 코드에 의해 뒷받침되는 것처럼 보이지만, 어쨌든 그 문장에 대한 추가 설명없이 PEP가 기술적으로 위반되었다고 말하는 것은 정확하지 않다고 생각합니다.
GrandOpener

2
@GrandOpener : 이는 001불법이지만 귀하의 해석은 합법적 인 것으로 간주합니다 ( "즉시"의 의미가 매우 명확해야하기 때문에).
nneonneo

좋은 지적. 따라서 PEP는 확실히 위반되었습니다. 모호한 것은 그것이 위반되는 정확한 성격입니다. :)
GrandOpener

17

특별한 경우 ( "0"+)

2.4.4. 정수 리터럴

정수 리터럴은 다음 어휘 정의로 설명됩니다.

정수 :: = decimalinteger | 옥틴 테거 | hexinteger | 비정 수
decimalinteger :: = 0이 아닌 숫자 * | "0"+
0이 아닌 숫자 :: = "1"... "9"
숫자 :: = "0"... "9"
8 진수 :: = "0"( "o"| "O") 8 진수 +
hexinteger :: = "0"( "x"| "X") 16 진수 +
bininteger :: = "0"( "b"| "B") bindigit +
8 진수 :: = "0"... "7"
16 진수 :: = 숫자 | "a"... "f"| "A"... "F"
bindigit :: = "0"| "1"

문법을 살펴보면 0특별한 경우 가 필요 하다는 것을 쉽게 알 수 있습니다 . 그래도 ' +'가 왜 필요한지 잘 모르겠습니다 . 개발 메일 링리스트를 살펴볼 시간입니다 ...


Python2에서, 둘 이상의 것을주의하는 것이 재미 0int로서 구문 분석 octinteger(최종 결과는 여전히 0하지만)

decimalinteger :: = 0이 아닌 숫자 * | "0"
8 진수 :: = "0"( "o"| "O") 8 진수 + | "0"8 진수 +

1
그리고 왜 있고 "0"+없는지 "0"아십니까?
lejlot

1
@lejlot, 아직은 아니지만 흥미가 있습니다. 확실히 사양하지만의 일부
존 라 Rooy

3

Python2는 선행 0을 사용하여 8 진수를 지정했습니다.

>>> 010
8

이 (? 오해의 소지가) 문제를 방지하려면, Python3 명시 적 접두사를 요구한다 0b, 0o, 0x:

>>> 0o10
8

15
질문은 남아 있습니다. 왜 00허용됩니까? (그리고 000, 0000등)
마이클 기어 리

4
@MichaelGeary : 모호 할 수 없기 때문에 (00000000은 기본에 관계없이 0 임) 제거하면 불필요하게 코드가 손상 될 수 있습니까? 여전히 이상합니다.
RemcoGerlich

5
내가 잘못 아니에요 경우, @RemcoGerlich 011에 관계없이베이스.
Holt

2
@Holt :하지만 "0"+ "1"을 허용합니까? 특별한 경우는 아마도 훨씬 더 혼란 스러울 것입니다.
RemcoGerlich

4
@RemcoGerlich 결코 그렇지 않을 것이라고 말한 적이 없습니다;) 나는 모호 할 수 없기 can't be ambiguous때문에 논쟁이 아니라고 말하고있었습니다 01. IMO,이 00경우는 0안되는 특수한 경우 입니다.
Holt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.