क्यों पायथन 3 "00" को 0 के लिए शाब्दिक के रूप में अनुमति देता है, लेकिन 1 के लिए "01" को शाब्दिक के रूप में अनुमति नहीं देता है?


111

क्यों पायथन 3 "00" को 0 के लिए शाब्दिक के रूप में अनुमति देता है, लेकिन 1 के लिए "01" को शाब्दिक के रूप में अनुमति नहीं देता है? क्या कोई अच्छा कारण है? यह असंगति मुझे चकरा देती है। (और हम पायथन 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
इसे अभी हटाया नहीं जा सकता है, या यह इस प्रश्न के साथ पिछड़ी संगतता को तोड़ देगा!
जॉन ला रूय जूल

जवाबों:


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"

उपलब्ध मेमोरी में क्या संग्रहीत किया जा सकता है इसके अलावा पूर्णांक शाब्दिक की लंबाई के लिए कोई सीमा नहीं है।

ध्यान दें कि शून्य शून्य दशमलव संख्या में अग्रणी शून्य की अनुमति नहीं है। यह सी-स्टाइल ऑक्टल शाब्दिक विस्मरण के लिए है, जिसे पायथन ने 3.0 संस्करण से पहले इस्तेमाल किया था।

जैसा कि यहां उल्लेख किया गया है, एक शून्य शून्य दशमलव संख्या में अग्रणी शून्य की अनुमति नहीं है। "0"+एक बहुत ही विशेष मामले के रूप में कानूनी है, जो पायथन 2 में मौजूद नहीं था :

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

SVN प्रतिबद्ध r55866 ने टोकन में PEP 3127 लागू किया, जो पुरानी 0<octal>संख्याओं को मना करता है । हालांकि, उत्सुकता से, यह इस नोट को भी जोड़ता है:

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

एक विशेष nonzeroध्वज के साथ जो केवल तभी फेंकता है SyntaxErrorयदि अंकों के निम्नलिखित अनुक्रम में एक गैर-अक्ष अंक होता है।

यह अजीब है क्योंकि PEP 3127 इस मामले की अनुमति नहीं देता है:

इस पीईपी का प्रस्ताव है कि पायथन 3.0 (और पायथन 3.0 पूर्वावलोकन मोड 2.6) में भाषा से एक प्रमुख शून्य का उपयोग करके एक ऑक्टल संख्या को निर्दिष्ट करने की क्षमता को हटा दिया जाएगा, और जब भी एक प्रमुख "0" होगा, तो सिंटैक्सएयर उठाया जाएगा। इसके तुरंत बाद एक और अंक

(जोर मेरा)

इसलिए, यह तथ्य कि एकाधिक शून्य की अनुमति है तकनीकी रूप से पीईपी का उल्लंघन कर रहा है, और मूल रूप से जॉर्ज ब्रैंडल द्वारा एक विशेष मामले के रूप में लागू किया गया था। उन्होंने नोट करने के लिए संबंधित दस्तावेज में बदलाव किया जो कि (पहले कवर किया गया था ) के "0"+लिए एक वैध मामला decimalintegerथा octinteger

हम शायद कभी पता नहीं चलेगा कि वास्तव में क्यों जोर्ज बनाने के लिए चुना है "0"+वैध - यह हमेशा के लिए पायथन में एक अजीब कोने मामले रह सकती है।


अद्यतन [२D जुलाई २०१५]: इस सवाल ने अजगर-विचारों पर एक जीवंत चर्चा सूत्र का नेतृत्व किया , जिसमें जॉर्ज ने इसमें भाग लिया :

स्टीवन डी 'अरानो ने लिखा:

इसे इस तरह परिभाषित क्यों किया गया? [...] हम शून्य पाने के लिए 0000 क्यों लिखेंगे?

मैं आपको बता सकता था, लेकिन फिर मुझे आपको मारना होगा।

जोर्ज

बाद में, इस विशेष रिपोर्ट से छुटकारा पाने के उद्देश्य से थ्रेड ने इस बग रिपोर्ट को जन्म दिया। यहाँ, जॉर्ज कहते हैं :

मुझे इस जानबूझकर परिवर्तन का कारण याद नहीं है (जैसा कि डॉक्स परिवर्तन से देखा जाता है)।

मैं इस बदलाव के लिए एक अच्छे कारण के साथ आने में असमर्थ हूँ [...]

और इस प्रकार हमारे पास है: इस असंगति के पीछे सटीक कारण समय के लिए खो गया है।

अंत में, ध्यान दें कि बग रिपोर्ट को अस्वीकार कर दिया गया था: अग्रणी शून्य को शेष पाइथर्स 3.x पर शून्य पूर्णांक पर स्वीकार किया जाना जारी रहेगा।


6
आप क्यों कहते हैं "हम शायद कभी नहीं जान पाएंगे कि जॉर्ज ने क्यों चुना ..."? अगर कोई जानता है कि वह इस धागे को देखता है और उसे इसके बारे में सूचित करता है, तो वह अपना जवाब दे सकता है! (जब तक आप नहीं जानते कि वह हमेशा के लिए अपने पिछले अजगर काम, या कुछ इसी तरह की परिस्थितियों पर चर्चा करने से इनकार कर रहा है)
वालरस

1
मुझे समझ नहीं आता कि उन्होंने सिर्फ दूसरा पायथन 2 octintegerकेस क्यों नहीं बनाया "0" octdigit*0C / C ++ में एक ऑक्टल शाब्दिक है।
रैंडम 832

1
वास्तव में अंग्रेजी इस संबंध में थोड़ी अस्पष्ट है। शब्द "एक और" का अर्थ "एक और" हो सकता है या इसका अर्थ "एक अलग" हो सकता है। PEP 3127 से बोल्ड किए गए उद्धरण की एक मान्य अंग्रेजी व्याख्या का अर्थ है "जब भी एक प्रमुख '0' को तुरंत एक अंक '0' के अलावा एक अंक के बाद उठाया जाएगा, तो मुझे यकीन नहीं होता कि क्या वास्तव में इरादा था ( हालाँकि यह व्याख्या वास्तविक कोड द्वारा समर्थित प्रतीत होती है), लेकिन किसी भी स्थिति में मुझे यह कहना सटीक नहीं है कि पीईपी को तकनीकी रूप से उस वाक्य के अतिरिक्त स्पष्टीकरण के बिना उल्लंघन किया जाता है।
ग्रैंडऑननर

2
@GrandOpener: ध्यान दें कि 001अवैध है, जबकि आपकी व्याख्या उस कानूनी को प्रस्तुत करती है (क्योंकि "तुरंत" का अर्थ काफी अस्पष्ट होना चाहिए)।
nnonneo

अच्छी बात। तो पीईपी निश्चित रूप से उल्लंघन किया जाता है; जो अस्पष्ट है वह सटीक प्रकृति है जिसमें उसका उल्लंघन किया जाता है। :)
GrandOpener

17

यह एक विशेष मामला है ( "0"+)

2.4.4। पूर्णांक शाब्दिक

निम्नलिखित शाब्दिक परिभाषाओं द्वारा पूर्णांक का वर्णन किया गया है:

पूर्णांक :: = दशांशक | सप्तक | hexinteger | bininteger
दशमलवप्रकारक :: = गैर-अक्षरीकृत अंक * | "0" +
नॉनजेरोडिज :: = "1" ... "9"
अंक :: = "0" ... "9"
ऑक्टिनटाइजर :: = "0" ("ओ" | "ओ") ऑक्टिडिज +
hexinteger :: = "0" ("x" | "X") hexdigit +
Bininteger :: = "0" ("b" | "B") bindigit +
अष्टमीत :: = "0" ... "7"
hexdigit :: = अंक | "ए" ... "एफ" | "ए एफ"
bindigit :: = "0" | "1"

यदि आप व्याकरण को देखते हैं, तो यह देखना आसान है कि 0एक विशेष मामले की आवश्यकता है। मुझे यकीन नहीं है कि क्यों ' +' वहाँ आवश्यक माना जाता है। देव मेलिंग सूची के माध्यम से खुदाई करने का समय ...


यह ध्यान रखना दिलचस्प है कि पायथन 2 में, एक से अधिक 0को एक के रूप में पार्स किया गया था octinteger(अंतिम परिणाम 0हालांकि अभी भी है)

दशमलवप्रकारक :: = गैर-अक्षरीकृत अंक * | "0"
ऑक्टिनटाइजर :: = "0" ("ओ" | "ओ") ऑक्टिडिज + | "0" अष्टकूट +

1
और कोई भी विचार क्यों है "0"+और क्या नहीं है "0"?
लेज्लोट

1
@lejlot, अभी तक नहीं - लेकिन मैं साज़िश कर रहा हूँ। यह निश्चित रूप से कल्पना का हिस्सा है
जॉन ला रोय जूल

3

पायथन 2 ने अष्टक संख्या निर्दिष्ट करने के लिए अग्रणी शून्य का उपयोग किया:

>>> 010
8

इस (? गुमराह) व्यवहार से बचने के लिए python3 स्पष्ट उपसर्गों की आवश्यकता है 0b, 0o, 0x:

>>> 0o10
8

15
सवाल यह है: 00अनुमति क्यों है ? (और 000, 0000आदि)
माइकल गियरी

4
@MichaelGeary: संभवतः क्योंकि यह अस्पष्ट नहीं हो सकता है (00000000 आधार की परवाह किए बिना 0 है) और इसे हटाने से अनावश्यक रूप से कोड टूट जाएगा? फिर भी अजीब है।
रेमकोगर्लिच

5
@RemcoGerlich यदि मैं गलत नहीं हूं, तो आधार की परवाह किए बिना 01भी 1
होल्ट

2
@ झटका: लेकिन "0" + "1" की अनुमति? एक विशेष मामले के रूप में शायद और भी अधिक भ्रामक होगा।
रेमकोगर्लिच

4
@RemcoGerlich ने कहा कि यह कभी नहीं होगा;) मैं सिर्फ यह कह रहा था कि can't be ambiguousयह एक तर्क नहीं है क्योंकि 01या तो अस्पष्ट नहीं हो सकता। IMO, 00मामला सिर्फ एक विशेष मामला है क्योंकि यह वह है 0जो नहीं होना चाहिए।
होल्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.