Python Language
Python 2 से Python 3 में जाने वाली असंगतताएँ
खोज…
परिचय
अधिकांश भाषाओं के विपरीत, पायथन दो प्रमुख संस्करणों का समर्थन करता है। 2008 के बाद से जब पायथन 3 को रिलीज़ किया गया था, कई लोगों ने संक्रमण किया है, जबकि कई ने नहीं किया है। दोनों को समझने के लिए, यह खंड पायथन 2 और पायथन 3 के बीच के महत्वपूर्ण अंतरों को शामिल करता है।
टिप्पणियों
वर्तमान में पायथन के दो समर्थित संस्करण हैं: 2.7 (पायथन 2) और 3.6 (पायथन 3)। इसके अतिरिक्त संस्करण 3.3 और 3.4 स्रोत प्रारूप में सुरक्षा अद्यतन प्राप्त करते हैं।
पायथन 2.7 पायथन के सबसे पुराने संस्करणों के साथ पीछे की ओर संगत है, और अजगर के अधिकांश 1.x और 2.x संस्करणों से पायथन कोड को अपरिवर्तित चला सकता है। यह व्यापक रूप से उपलब्ध है, जिसमें संकुल का व्यापक संग्रह है। यह सीपीथॉन डेवलपर्स द्वारा पदावनत भी माना जाता है, और केवल सुरक्षा और बग-फिक्स विकास प्राप्त करता है। सीपीथॉन डेवलपर्स ने 2020 में भाषा के इस संस्करण को छोड़ने का इरादा किया है।
पाइथन एन्हांसमेंट प्रपोजल 373 के अनुसार, 25 जून 2016 के बाद पाइथन 2 की भविष्य की कोई योजना नहीं है, लेकिन बग फिक्स और सुरक्षा अपडेट को 2020 तक समर्थित किया जाएगा। (यह निर्दिष्ट नहीं करता है कि 2020 में सही तारीख पाइथन की सूर्यास्त की तारीख होगी। 2.)
पायथन 3 जानबूझकर पीछे की ओर-संगतता तोड़ दिया, भाषा डेवलपर्स को भाषा के मूल के साथ होने वाली चिंताओं को दूर करने के लिए। पायथन 3 को नया विकास और नई सुविधाएँ प्राप्त होती हैं। यह भाषा का संस्करण है जिसे भाषा डेवलपर आगे बढ़ने का इरादा रखते हैं।
Python 3.0 की प्रारंभिक रिलीज़ और वर्तमान संस्करण के बीच के समय में, Python 3 की कुछ विशेषताओं को Python 2.6 में वापस पोर्ट किया गया था, और Python 3 के अन्य भागों को Python 2 के साथ सिंटैक्स संगत किया गया था। इसलिए इसे लिखना संभव है। अजगर जो भविष्य के आयात और विशेष मॉड्यूल (जैसे छह ) का उपयोग करके पायथन 2 और पायथन 3 दोनों पर काम करेगा।
भविष्य के आयात को आपके मॉड्यूल की शुरुआत में होना चाहिए:
from __future__ import print_function
# other imports and instructions go after __future__
print('Hello world')
__future__
मॉड्यूल पर अधिक जानकारी के लिए, पायथन प्रलेखन में संबंधित पृष्ठ देखें।
2to3 टूल एक पायथन प्रोग्राम है जो Python 2.x कोड को Python 3.x कोड में परिवर्तित करता है, Python प्रलेखन भी देखें।
पैकेज छह पायथन 2/3 संगतता के लिए उपयोगिताओं प्रदान करता है:
- नामांकित पुस्तकालयों तक एकीकृत पहुंच
- स्ट्रिंग / यूनिकोड प्रकारों के लिए चर
- विधि के लिए कार्य जो हटा दिया गया है या उसका नाम बदल दिया गया है
पायथन 2 और पायथन 3 के बीच अंतर का एक संदर्भ यहां पाया जा सकता है ।
प्रिंट स्टेटमेंट बनाम प्रिंट फंक्शन
पायथन 2 में, print
एक बयान है:
print "Hello World"
print # print a newline
print "No newline", # add trailing comma to remove newline
print >>sys.stderr, "Error" # print to stderr
print("hello") # print "hello", since ("hello") == "hello"
print() # print an empty tuple "()"
print 1, 2, 3 # print space-separated arguments: "1 2 3"
print(1, 2, 3) # print tuple "(1, 2, 3)"
पायथन 3 में, print()
एक फ़ंक्शन है, जिसमें सामान्य उपयोगों के लिए कीवर्ड तर्क हैं:
print "Hello World" # SyntaxError
print("Hello World")
print() # print a newline (must use parentheses)
print("No newline", end="") # end specifies what to append (defaults to newline)
print("Error", file=sys.stderr) # file specifies the output buffer
print("Comma", "separated", "output", sep=",") # sep specifies the separator
print("A", "B", "C", sep="") # null string for sep: prints as ABC
print("Flush this", flush=True) # flush the output buffer, added in Python 3.3
print(1, 2, 3) # print space-separated arguments: "1 2 3"
print((1, 2, 3)) # print tuple "(1, 2, 3)"
प्रिंट फ़ंक्शन में निम्नलिखित पैरामीटर हैं:
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
sep
वह है जो आपके द्वारा प्रिंट की जाने वाली वस्तुओं को अलग करता है। उदाहरण के लिए:
print('foo', 'bar', sep='~') # out: foo~bar
print('foo', 'bar', sep='.') # out: foo.bar
end
वह है जो प्रिंट स्टेटमेंट का अंत है। उदाहरण के लिए:
print('foo', 'bar', end='!') # out: foo bar!
नॉन-न्यूलाइन एंडिंग प्रिंट स्टेटमेंट के बाद फिर से प्रिंटिंग उसी लाइन पर प्रिंट होगी :
print('foo', end='~')
print('bar')
# out: foo~bar
नोट: भविष्य की अनुकूलता के लिए, print
फंक्शन पायथन 2.6 में भी उपलब्ध है; हालांकि इसका उपयोग तब तक नहीं किया जा सकता जब तक कि print
स्टेटमेंट के पार्सिंग के साथ अक्षम न किया जाए
from __future__ import print_function
इस फ़ंक्शन के पास पायथन 3 के समान प्रारूप है, सिवाय इसके कि इसमें flush
पैरामीटर का अभाव है।
तर्क के लिए PEP 3105 देखें।
स्ट्रिंग्स: बाइट्स बनाम यूनिकोड
पायथन 2 में स्ट्रिंग के दो वेरिएंट होते हैं: जो बाइट्स से बने होते हैं टाइप ( str
) और जो टेक्स्ट से बने होते हैं टाइप ( unicode
)।
पायथन 2 में, टाइप str
का एक ऑब्जेक्ट हमेशा एक बाइट अनुक्रम होता है, लेकिन आमतौर पर पाठ और बाइनरी डेटा दोनों के लिए उपयोग किया जाता है।
एक स्ट्रिंग शाब्दिक को बाइट स्ट्रिंग के रूप में व्याख्या की जाती है।
s = 'Cafe' # type(s) == str
दो अपवाद हैं: आप u
साथ शाब्दिक उपसर्ग द्वारा स्पष्ट रूप से एक यूनिकोड (पाठ) को परिभाषित कर सकते हैं:
s = u'Café' # type(s) == unicode
b = 'Lorem ipsum' # type(b) == str
वैकल्पिक रूप से, आप यह निर्दिष्ट कर सकते हैं कि एक पूरे मॉड्यूल के स्ट्रिंग शाब्दिकों को यूनिकोड (पाठ) शब्द बनाने चाहिए:
from __future__ import unicode_literals
s = 'Café' # type(s) == unicode
b = 'Lorem ipsum' # type(b) == unicode
यह जांचने के लिए कि आपका चर एक स्ट्रिंग है (या तो यूनिकोड या बाइट स्ट्रिंग), आप उपयोग कर सकते हैं:
isinstance(s, basestring)
पायथन 3 में, str
प्रकार एक यूनिकोड पाठ प्रकार है।
s = 'Cafe' # type(s) == str
s = 'Café' # type(s) == str (note the accented trailing e)
इसके अतिरिक्त, पायथन 3 ने एक bytes
ऑब्जेक्ट जोड़ा, जो बाइनरी "ब्लब्स" या एन्कोडिंग-स्वतंत्र फ़ाइलों के लिए लिखने के लिए उपयुक्त है। बाइट्स ऑब्जेक्ट बनाने के लिए, आप b
को एक स्ट्रिंग शाब्दिक में उपसर्ग कर सकते हैं या स्ट्रिंग के encode
विधि को कॉल कर सकते हैं:
# Or, if you really need a byte string:
s = b'Cafe' # type(s) == bytes
s = 'Café'.encode() # type(s) == bytes
यह जांचने के लिए कि क्या मान एक स्ट्रिंग है, का उपयोग करें:
isinstance(s, str)
पायथन 2 और पायथन 3 कोड बेस के बीच संगतता को कम करने के लिए एक u
प्रीफिक्स के साथ स्ट्रिंग लिटरल को उपसर्ग करना भी संभव है। चूंकि, पायथन 3 में, सभी स्ट्रिंग्स यूनिकोड डिफ़ॉल्ट रूप से हैं, u
साथ एक स्ट्रिंग शाब्दिक को प्रस्तुत करने का कोई प्रभाव नहीं है:
u'Cafe' == 'Cafe'
अजगर 2 के कच्चे यूनिकोड स्ट्रिंग उपसर्ग ur
समर्थित नहीं है, हालांकि:
>>> ur'Café'
File "<stdin>", line 1
ur'Café'
^
SyntaxError: invalid syntax
ध्यान दें कि आपको उस पाठ के bytes
प्रतिनिधित्व में परिवर्तित करने के लिए पायथन 3 टेक्स्ट ( str
) ऑब्जेक्ट को encode
करना होगा। इस विधि का डिफ़ॉल्ट एन्कोडिंग UTF-8 है ।
आप यूनिकोड पाठ का प्रतिनिधित्व करने के लिए bytes
ऑब्जेक्ट पूछने के लिए decode
का उपयोग कर सकते हैं:
>>> b.decode()
'Café'
जबकि bytes
प्रकार पायथन 2 और 3 दोनों में मौजूद है, unicode
प्रकार केवल पायथन 2 में मौजूद है। पायथन 3 के अंतर्निहित यूनिकोड तार को पायथन 2 में उपयोग करने के लिए, अपनी कोड फ़ाइल के शीर्ष पर निम्न जोड़ें
from __future__ import unicode_literals
print(repr("hi"))
# u'hi'
एक और महत्वपूर्ण अंतर यह है कि पायथन 3 में बाइट्स को अनुक्रमित करने से एक int
आउटपुट में परिणाम मिलता है:
b"abc"[0] == 97
1 बाइट ऑब्जेक्ट में एक परिणाम के आकार में टुकड़ा करते हुए:
b"abc"[0:1] == b"a"
इसके अलावा, पायथन 3 यूनिकोड के साथ कुछ असामान्य व्यवहार को ठीक करता है , अर्थात पायथन 2 में बाइट के तारों को उलट देना। उदाहरण के लिए, निम्न समस्या हल हो गई है:
# -*- coding: utf8 -*-
print("Hi, my name is Łukasz Langa.")
print(u"Hi, my name is Łukasz Langa."[::-1])
print("Hi, my name is Łukasz Langa."[::-1])
# Output in Python 2
# Hi, my name is Łukasz Langa.
# .agnaL zsakuŁ si eman ym ,iH
# .agnaL zsaku�� si eman ym ,iH
# Output in Python 3
# Hi, my name is Łukasz Langa.
# .agnaL zsakuŁ si eman ym ,iH
# .agnaL zsakuŁ si eman ym ,iH
इंटेगर डिवीजन
पूर्णांक पर लागू होने पर मानक विभाजन चिन्ह ( /
) पायथन 3 और पायथन 2 में भिन्न रूप से संचालित होता है।
पायथन 3 में एक पूर्णांक द्वारा एक पूर्णांक को विभाजित करते समय, विभाजन ऑपरेशन x / y
एक सच्चे विभाजन ( __truediv__
विधि का उपयोग करता है) का प्रतिनिधित्व करता है और एक अस्थायी बिंदु परिणाम पैदा करता है। इस बीच, पायथन 2 में एक ही ऑपरेशन एक क्लासिक डिवीजन का प्रतिनिधित्व करता है जो परिणाम को नकारात्मक अनंतता की ओर ले जाता है (जिसे मंजिल लेने के रूप में भी जाना जाता है)।
उदाहरण के लिए:
कोड | पायथन 2 आउटपुट | पायथन 3 आउटपुट |
---|---|---|
3 / 2 | 1 | 1.5 |
2 / 3 | 0 | 0.6666666666666666 |
-3 / 2 | -2 | -1.5 |
राउंड-प्रति-शून्य व्यवहार पायथन 2.2 में पदावनत किया गया था, लेकिन पिछड़े संगतता के लिए पायथन 2.7 में रहता है और पायथन 3 में हटा दिया गया था।
नोट: पायथन 2 (बिना फर्श के गोलाई में) में एक फ्लोट परिणाम प्राप्त करने के लिए हम दशमलव बिंदु के साथ किसी एक ऑपरेंड को निर्दिष्ट कर सकते हैं। 2/3
का उपरोक्त उदाहरण जो पायथन 2 में 0
देता है, का उपयोग 2 / 3.0
या 2.0 / 3
या 2.0/3.0
के रूप में 0.6666666666666666
प्राप्त करने के लिए किया 0.6666666666666666
कोड | पायथन 2 आउटपुट | पायथन 3 आउटपुट |
---|---|---|
3.0 / 2.0 | 1.5 | 1.5 |
2 / 3.0 | 0.6666666666666666 | 0.6666666666666666 |
-3.0 / 2 | -1.5 | -1.5 |
फ्लोर डिवीजन ऑपरेटर ( //
) भी है, जो दोनों संस्करणों में एक ही तरह से काम करता है: यह निकटतम पूर्णांक तक गोल होता है। (हालांकि फ्लोट के साथ उपयोग किए जाने पर एक फ्लोट लौटाया जाता है) दोनों संस्करणों में //
ऑपरेटर नक्शे से __floordiv__
।
कोड | पायथन 2 आउटपुट | पायथन 3 आउटपुट |
---|---|---|
3 // 2 | 1 | 1 |
2 // 3 | 0 | 0 |
-3 // 2 | -2 | -2 |
3.0 // 2.0 | 1.0 | 1.0 |
2.0 // 3 | 0.0 | 0.0 |
-3 // 2.0 | -2.0 | -2.0 |
एक operator
मॉड्यूल में मूल कार्यों का उपयोग करके स्पष्ट रूप से सच्चे विभाजन या फर्श विभाजन को लागू कर सकता है:
from operator import truediv, floordiv
assert truediv(10, 8) == 1.25 # equivalent to `/` in Python 3
assert floordiv(10, 8) == 1 # equivalent to `//`
जबकि स्पष्ट और स्पष्ट, हर विभाजन के लिए ऑपरेटर कार्यों का उपयोग करना थकाऊ हो सकता है। /
ऑपरेटर के व्यवहार को बदलना अक्सर पसंद किया जाएगा। एक सामान्य अभ्यास प्रत्येक मॉड्यूल में पहले बयान के रूप में from __future__ import division
जोड़कर विशिष्ट विभाजन व्यवहार को समाप्त करना है:
# needs to be the first statement in a module
from __future__ import division
कोड | पायथन 2 आउटपुट | पायथन 3 आउटपुट |
---|---|---|
3 / 2 | 1.5 | 1.5 |
2 / 3 | 0.6666666666666666 | 0.6666666666666666 |
-3 / 2 | -1.5 | -1.5 |
from __future__ import division
गारंटी देता है कि /
ऑपरेटर सही डिवीजन का प्रतिनिधित्व करता है और केवल उन मॉड्यूल्स के भीतर है जिनमें __future__
इंपोर्ट होता है, इसलिए सभी नए मॉड्यूल्स में इसे सक्षम नहीं करने के लिए कोई बाध्यकारी कारण नहीं हैं।
नोट : कुछ अन्य प्रोग्रामिंग भाषाएं ऋणात्मक अनंतता की ओर चक्कर लगाने के बजाय शून्य (ट्रंकेशन) की ओर राउंडिंग का उपयोग करती हैं जैसा कि पायथन करता है (अर्थात उन भाषाओं में -3 / 2 == -1
)। कोड को पोर्ट करते या तुलना करते समय यह व्यवहार भ्रम पैदा कर सकता है।
फ्लोट ऑपरेंड पर ध्यान दें : from __future__ import division
एक विकल्प के रूप में, कोई सामान्य डिवीजन सिंबल का उपयोग कर सकता है /
और यह सुनिश्चित कर सकता है कि कम से कम ऑपरेंड में से एक फ्लोट है: 3 / 2.0 == 1.5
। हालांकि, यह बुरा अभ्यास माना जा सकता है। average = sum(items) / len(items)
लिखना बहुत आसान है और तैरने के लिए किसी एक तर्क को देना भूल जाते हैं। इसके अलावा, ऐसे मामले अक्सर परीक्षण के दौरान नोटिस से बच सकते हैं, उदाहरण के लिए, यदि आप float
एस युक्त सरणी पर परीक्षण करते हैं, लेकिन उत्पादन में int
की एक सरणी प्राप्त करते हैं। इसके अतिरिक्त, यदि समान कोड का उपयोग पायथन 3 में किया जाता है, तो ऐसे प्रोग्राम जो 3/2 3 / 2 == 1
के सही होने की उम्मीद करते हैं, सही ढंग से काम नहीं करेंगे।
अधिक विस्तृत तर्क के लिए PEP 238 देखें कि पायथन 3 में डिवीजन ऑपरेटर को क्यों बदला गया और पुराने शैली के विभाजन को टाला क्यों जाना चाहिए।
विभाजन के बारे में अधिक जानने के लिए सरल गणित विषय देखें।
कम करना अब बिल्ट-इन नहीं है
पायथन 2 में, reduce
या तो बिल्ट-इन फ़ंक्शन के रूप में या functools
पैकेज (संस्करण 2.6 इसके बाद) से उपलब्ध है, जबकि पायथन 3 में reduce
केवल functools
से ही उपलब्ध है। हालाँकि Python2 और Python3 दोनों में reduce
लिए वाक्यविन्यास समान है और यह reduce(function_to_reduce, list_to_reduce)
।
एक उदाहरण के रूप में, आइए हम प्रत्येक सूची को आसन्न संख्याओं में विभाजित करके एक मान को कम करने पर विचार करें। यहां हम operator
लाइब्रेरी से truediv
फ़ंक्शन का उपयोग करते हैं।
पायथन 2.x में यह उतना ही सरल है:
>>> my_list = [1, 2, 3, 4, 5]
>>> import operator
>>> reduce(operator.truediv, my_list)
0.008333333333333333
पायथन 3.x में उदाहरण थोड़ा और जटिल हो जाता है:
>>> my_list = [1, 2, 3, 4, 5]
>>> import operator, functools
>>> functools.reduce(operator.truediv, my_list)
0.008333333333333333
हम नेमस्पेस नाम के साथ कॉल reduce
from functools import reduce
करने से बचने के लिए from functools import reduce
भी उपयोग कर सकते हैं।
सीमा और xrange कार्यों के बीच अंतर
पायथन 2 में, range
फ़ंक्शन एक सूची देता है जबकि xrange
एक विशेष xrange
ऑब्जेक्ट बनाता है, जो एक अपरिवर्तनीय अनुक्रम है, जो अन्य अंतर्निहित अनुक्रम प्रकारों के विपरीत, स्लाइसिंग का समर्थन नहीं करता है और न तो index
और न ही तरीकों की count
है:
print(range(1, 10))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(isinstance(range(1, 10), list))
# Out: True
print(xrange(1, 10))
# Out: xrange(1, 10)
print(isinstance(xrange(1, 10), xrange))
# Out: True
पायथन 3 में, xrange
को range
अनुक्रम में विस्तारित किया गया था, जो अब एक range
ऑब्जेक्ट बनाता है। कोई xrange
प्रकार नहीं है:
print(range(1, 10))
# Out: range(1, 10)
print(isinstance(range(1, 10), range))
# Out: True
# print(xrange(1, 10))
# The output will be:
#Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
#NameError: name 'xrange' is not defined
इसके अतिरिक्त, पायथन 3.2 के बाद से, range
स्लाइसिंग, index
और count
का भी समर्थन करती है:
print(range(1, 10)[3:7])
# Out: range(3, 7)
print(range(1, 10).count(5))
# Out: 1
print(range(1, 10).index(7))
# Out: 6
एक सूची के बजाय एक विशेष अनुक्रम प्रकार का उपयोग करने का लाभ यह है कि दुभाषिया को किसी सूची के लिए मेमोरी आवंटित करने की आवश्यकता नहीं होती है और उसे पॉप्युलेट करना होता है:
# range(10000000000000000)
# The output would be:
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# MemoryError
print(xrange(100000000000000000))
# Out: xrange(100000000000000000)
चूंकि बाद वाला व्यवहार आम तौर पर वांछित है, पूर्व को पायथन 3 में हटा दिया गया था। यदि आप अभी भी पायथन 3 में एक सूची रखना चाहते हैं, तो आप बस range
वस्तु पर list()
निर्माता का उपयोग कर सकते हैं:
print(list(range(1, 10)))
# Out: [1, 2, 3, 4, 5, 6, 7, 8, 9]
अनुकूलता
पायथन 2.x और पायथन 3.x दोनों संस्करणों के बीच संगतता बनाए रखने के लिए, आप फॉरवर्ड-कॉम्पिटिटैलिटी और बैकवर्ड- builtins
दोनों को प्राप्त करने के लिए बाहरी पैकेज future
से निर्मित मॉड्यूल का उपयोग कर सकते हैं:
#forward-compatible
from builtins import range
for i in range(10**8):
pass
#backward-compatible
from past.builtins import xrange
for i in xrange(10**8):
pass
future
लाइब्रेरी में range
सभी पायथन संस्करणों में स्लाइसिंग, index
और count
का समर्थन करती है, बिल्कुल पाइथन 3.2+ पर बिल्ट-इन विधि की तरह।
Iterables खोलना
पायथन 3 में, आप इसमें आइटम्स की सटीक संख्या को जाने बिना एक पुनरावृत्ति को अनपैक कर सकते हैं, और यहां तक कि वेरिएबल के अंत में एक वैरिएबल होल्ड भी कर सकते हैं। उसके लिए, आप एक चर प्रदान करते हैं जो मानों की सूची एकत्र कर सकता है। यह नाम के पहले तारांकन चिह्न लगाकर किया जाता है। उदाहरण के लिए, किसी list
खोलना:
first, second, *tail, last = [1, 2, 3, 4, 5]
print(first)
# Out: 1
print(second)
# Out: 2
print(tail)
# Out: [3, 4]
print(last)
# Out: 5
नोट : *variable
सिंटैक्स का उपयोग करते समय, variable
हमेशा एक सूची होगी, भले ही मूल प्रकार एक सूची न हो। इसमें मूल सूची में तत्वों की संख्या के आधार पर शून्य या अधिक तत्व हो सकते हैं।
first, second, *tail, last = [1, 2, 3, 4]
print(tail)
# Out: [3]
first, second, *tail, last = [1, 2, 3]
print(tail)
# Out: []
print(last)
# Out: 3
इसी तरह, एक str
खोलना:
begin, *tail = "Hello"
print(begin)
# Out: 'H'
print(tail)
# Out: ['e', 'l', 'l', 'o']
एक date
unpacking का उदाहरण; _
का उपयोग इस उदाहरण में एक प्रचलित चर के रूप में किया जाता है (हम केवल year
मान में रुचि रखते हैं):
person = ('John', 'Doe', (10, 16, 2016))
*_, (*_, year_of_birth) = person
print(year_of_birth)
# Out: 2016
यह ध्यान देने योग्य है कि, चूँकि आइटम की एक परिवर्तनीय संख्या को *
खा लेता है, आप एक असाइनमेंट में एक ही चलने के लिए दो *
s नहीं कर सकते - यह नहीं पता होगा कि कितने तत्व पहले अनपैकिंग में जाते हैं, और दूसरे में कितने :
*head, *tail = [1, 2]
# Out: SyntaxError: two starred expressions in assignment
अब तक हमने असाइनमेंट में अनपैकिंग पर चर्चा की है। *
और **
को पायथन 3.5 में बढ़ाया गया था । अब एक अभिव्यक्ति में कई अनपैकिंग ऑपरेशन करना संभव है:
{*range(4), 4, *(5, 6, 7)}
# Out: {0, 1, 2, 3, 4, 5, 6, 7}
फ़ंक्शन तर्कों में एक पुनरावृत्ति को खोलना भी संभव है:
iterable = [1, 2, 3, 4, 5]
print(iterable)
# Out: [1, 2, 3, 4, 5]
print(*iterable)
# Out: 1 2 3 4 5
शब्दकोश को खोलना दो आसन्न सितारों का उपयोग करता है **
( पीईपी 448 ):
tail = {'y': 2, 'z': 3}
{'x': 1, **tail}
# Out: {'x': 1, 'y': 2, 'z': 3}
यह पुराने मूल्यों को समझने और शब्दकोशों के विलय दोनों के लिए अनुमति देता है।
dict1 = {'x': 1, 'y': 1}
dict2 = {'y': 2, 'z': 3}
{**dict1, **dict2}
# Out: {'x': 1, 'y': 2, 'z': 3}
पायथन 3 ने कार्यों में टपल अनपैकिंग को हटा दिया। इसलिए पायथन 3 में निम्नलिखित काम नहीं करता है
# Works in Python 2, but syntax error in Python 3:
map(lambda (x, y): x + y, zip(range(5), range(5)))
# Same is true for non-lambdas:
def example((x, y)):
pass
# Works in both Python 2 and Python 3:
map(lambda x: x[0] + x[1], zip(range(5), range(5)))
# And non-lambdas, too:
def working_example(x_y):
x, y = x_y
pass
विस्तृत तर्क के लिए PEP 3113 देखें।
अपवाद उठाना और संभालना
यह पायथन 2 सिंटैक्स है, कॉमा पर ध्यान दें ,
raise
और लाइनों except
:
try:
raise IOError, "input/output error"
except IOError, exc:
print exc
पायथन 3 में ,
सिंटैक्स को गिरा दिया जाता है और इसे कोष्ठक और खोजशब्द के as
बदल दिया जाता है:
try:
raise IOError("input/output error")
except IOError as exc:
print(exc)
पीछे की संगतता के लिए, पायथन 3 सिंटैक्स भी पायथन 2.6 में उपलब्ध है, इसलिए इसका उपयोग उन सभी नए कोड के लिए किया जाना चाहिए, जिन्हें पिछले संस्करणों के साथ संगत करने की आवश्यकता नहीं है।
पायथन 3 भी अपवाद को जोड़ता है , जिसमें आप यह संकेत कर सकते हैं कि कुछ अन्य अपवाद इस अपवाद का कारण थे । उदाहरण के लिए
try:
file = open('database.db')
except FileNotFoundError as e:
raise DatabaseError('Cannot open {}') from e
अपवाद में उठाया except
बयान प्रकार का है DatabaseError
, लेकिन मूल अपवाद के रूप में चिह्नित है __cause__
कि अपवाद की विशेषता। जब ट्रेसबैक प्रदर्शित किया जाता है, तो मूल अपवाद भी ट्रेसबैक में प्रदर्शित किया जाएगा:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
FileNotFoundError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')
यदि आप स्पष्ट चिनिंग के बिना एक except
खंड में फेंकते हैं:
try:
file = open('database.db')
except FileNotFoundError as e:
raise DatabaseError('Cannot open {}')
ट्रेसबैक है
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
FileNotFoundError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')
पाइथन 2.x में न तो किसी का समर्थन किया जाता है; मूल अपवाद और इसका ट्रेसबैक खो जाएगा यदि अपवाद को छोड़कर एक और अपवाद है। निम्नलिखित कोड संगतता के लिए इस्तेमाल किया जा सकता है:
import sys
import traceback
try:
funcWithError()
except:
sys_vers = getattr(sys, 'version_info', (0,))
if sys_vers < (3, 0):
traceback.print_exc()
raise Exception("new exception")
पहले से फेंक दिए गए अपवाद को "भूल" करने के raise from None
उपयोग करें
try:
file = open('database.db')
except FileNotFoundError as e:
raise DatabaseError('Cannot open {}') from None
अब ट्रेसबैक बस होगा
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
DatabaseError('Cannot open database.db')
या इसे पायथन 2 और 3 दोनों के साथ संगत बनाने के लिए आप इस तरह छह पैकेज का उपयोग कर सकते हैं:
import six
try:
file = open('database.db')
except FileNotFoundError as e:
six.raise_from(DatabaseError('Cannot open {}'), None)
.next () नाम बदलकर पुनरावृत्तियों पर विधि
पायथन 2 में, इट्रेटर पर next
विधि नामक एक विधि का उपयोग करके एक पुनरावृत्ति का पता लगाया जा सकता है:
g = (i for i in range(0, 3))
g.next() # Yields 0
g.next() # Yields 1
g.next() # Yields 2
पायथन 3 में .next
मेथड का नाम बदलकर .__next__
रखा गया है, इसकी "जादू" भूमिका को स्वीकार करते हुए, इसलिए .next
कॉलिंग एक AttributeError
को बढ़ाएगा। पायथन 2 और पायथन 3 दोनों में इस कार्यक्षमता का उपयोग करने का सही तरीका next
फ़ंक्शन को एक तर्क के रूप में पुनरावृत्त के साथ कॉल करना है।
g = (i for i in range(0, 3))
next(g) # Yields 0
next(g) # Yields 1
next(g) # Yields 2
यह कोड 2.6 से लेकर वर्तमान रिलीज़ तक के संस्करणों में पोर्टेबल है।
विभिन्न प्रकारों की तुलना
विभिन्न प्रकार की वस्तुओं की तुलना की जा सकती है। परिणाम मनमाने हैं, लेकिन सुसंगत हैं। उन्हें ऐसा आदेश दिया जाता है कि None
भी किसी भी चीज़ से कम None
है, संख्यात्मक प्रकार गैर-संख्यात्मक प्रकारों की तुलना में छोटे होते हैं, और बाकी सभी चीज़ों को क्रमबद्ध रूप से टाइप किया जाता है। इस प्रकार, एक int
एक str
से कम है और एक tuple
list
से अधिक है:
[1, 2] > 'foo'
# Out: False
(1, 2) > 'foo'
# Out: True
[1, 2] > (1, 2)
# Out: False
100 < [1, 'x'] < 'xyz' < (1, 'x')
# Out: True
यह मूल रूप से किया गया था इसलिए मिश्रित प्रकारों की एक सूची को सॉर्ट किया जा सकता है और वस्तुओं को एक साथ टाइप करके समूहीकृत किया जाएगा:
l = [7, 'x', (1, 2), [5, 6], 5, 8.0, 'y', 1.2, [7, 8], 'z']
sorted(l)
# Out: [1.2, 5, 7, 8.0, [5, 6], [7, 8], 'x', 'y', 'z', (1, 2)]
भिन्न (गैर-संख्यात्मक) प्रकारों की तुलना करते समय एक अपवाद उठाया जाता है:
1 < 1.5
# Out: True
[1, 2] > 'foo'
# TypeError: unorderable types: list() > str()
(1, 2) > 'foo'
# TypeError: unorderable types: tuple() > str()
[1, 2] > (1, 2)
# TypeError: unorderable types: list() > tuple()
पायथन 3 में मिश्रित सूचियों को प्रकारों के आधार पर क्रमबद्ध करने और संस्करणों के बीच अनुकूलता प्राप्त करने के लिए, आपको क्रमबद्ध फ़ंक्शन के लिए एक कुंजी प्रदान करनी होगी:
>>> list = [1, 'hello', [3, 4], {'python': 2}, 'stackoverflow', 8, {'python': 3}, [5, 6]]
>>> sorted(list, key=str)
# Out: [1, 8, [3, 4], [5, 6], 'hello', 'stackoverflow', {'python': 2}, {'python': 3}]
key
फ़ंक्शन के रूप में str
का उपयोग अस्थायी रूप से तुलना के प्रयोजनों के लिए अस्थायी रूप से प्रत्येक आइटम को स्ट्रिंग में परिवर्तित करता है। यह तब [
, '
, {
या 0-9
शुरू होने वाले स्ट्रिंग प्रतिनिधित्व को देखता है और यह उन (और सभी निम्नलिखित वर्णों) को क्रमबद्ध करने में सक्षम है।
उपयोगकर्ता का निवेश
Python 2 में, उपयोगकर्ता इनपुट को raw_input
फ़ंक्शन का उपयोग करके स्वीकार किया raw_input
है,
user_input = raw_input()
जबकि पायथन 3 में उपयोगकर्ता इनपुट input
फ़ंक्शन का उपयोग करके स्वीकार किया जाता है।
user_input = input()
पायथन 2 में, input
फ़ंक्शन input
को स्वीकार करेगा और इसकी व्याख्या करेगा। हालांकि यह उपयोगी हो सकता है, इसमें कई सुरक्षा विचार हैं और इसे पायथन 3 में हटा दिया गया था। समान कार्यक्षमता का उपयोग करने के लिए, eval(input())
का उपयोग किया जा सकता है।
दो संस्करणों में एक स्क्रिप्ट को पोर्टेबल रखने के लिए, आप नीचे दिए गए कोड को अपनी पायथन स्क्रिप्ट के शीर्ष के पास रख सकते हैं:
try:
input = raw_input
except NameError:
pass
शब्दकोश विधि बदल जाती है
पायथन 3 में, कई शब्दकोश विधियाँ पायथन 2 से व्यवहार में काफी भिन्न हैं, और कई को हटा दिया गया था: has_key
, iter*
और view*
चला गया है। d.has_key(key)
बजाय, जिसे लंबे समय से हटा दिया गया था, किसी को अब key in d
उपयोग करना होगा।
पायथन 2 में, शब्दकोश विधियाँ keys
, values
और items
सूची को लौटाती हैं। पायथन 3 में वे बदले की वस्तुओं को देखते हैं; दृश्य ऑब्जेक्ट पुनरावृत्त नहीं हैं, और वे उनसे दो तरीकों से भिन्न होते हैं, अर्थात्:
- उनके पास आकार है (उन पर
len
फ़ंक्शन का उपयोग कर सकते हैं) - उन्हें कई बार पुनरावृत्त किया जा सकता है
इसके अतिरिक्त, पुनरावृत्तियों के साथ, शब्दकोश में परिवर्तन दृश्य वस्तुओं में परिलक्षित होते हैं।
पायथन 2.7 ने पायथन 3 से इन तरीकों को वापस ला दिया है; वे viewkeys
, viewvalues
और viewitems
रूप में उपलब्ध हैं। पायथन 2 कोड को पायथन 3 कोड में बदलने के लिए, संबंधित रूप निम्न हैं:
-
d.keys()
,d.values()
औरd.items()
पायथन 2 कीlist(d.keys())
परिवर्तित किया जाना चाहिएlist(d.keys())
,list(d.values())
औरlist(d.values())
औरlist(d.items())
-
d.iterkeys()
,d.itervalues()
औरd.iteritems()
कोiter(d.keys())
, या इससे भी बेहतर,iter(d)
बदला जाना चाहिए;iter(d.values())
औरiter(d.items())
क्रमशः - और अंत में अजगर 2.7 विधि कॉल
d.viewkeys()
,d.viewvalues()
औरd.viewitems()
के साथ बदला जा सकता हैd.keys()
,d.values()
औरd.items()
।
पोर्टिंग अजगर 2 कोड कि शब्दकोश कुंजियों, मानों या अधिक आइटम को दोहराता है, जबकि यह परिवर्तनशील कभी कभी मुश्किल है। विचार करें:
d = {'a': 0, 'b': 1, 'c': 2, '!': 3}
for key in d.keys():
if key.isalpha():
del d[key]
कोड ऐसा लगता है जैसे कि यह पायथन 3 में समान रूप से काम करेगा, लेकिन वहां keys
विधि एक दृश्य ऑब्जेक्ट को लौटाती है, न कि किसी सूची को, और यदि इसे ओवररेटेड करते समय शब्दकोश का आकार बदलता है, तो पायथन 3 कोड RuntimeError: dictionary changed size during iteration
साथ दुर्घटनाग्रस्त हो जाएगा RuntimeError: dictionary changed size during iteration
। समाधान for key in list(d)
लिए ठीक से लिखने के for key in list(d)
।
इसी प्रकार, दृश्य वस्तुएं पुनरावृत्तियों से अलग व्यवहार करती हैं: कोई उन पर next()
उपयोग नहीं कर सकता है, और एक पुनरावृत्ति को फिर से शुरू नहीं कर सकता है; इसके बजाय यह पुनः आरंभ होगा; यदि पायथन 2 कोड d.iterkeys()
, d.itervalues()
या d.iteritems()
के रिटर्न मान को d.iterkeys()
करता है , जो एक पुनरावृत्त के बजाय एक पुनरावृत्ति की अपेक्षा करता है , तो वह iter(d)
, iter(d.values())
iter(d)
होना चाहिए। अजगर 3 में iter(d.values())
या iter(d.items())
।
निष्पादित बयान पायथन 3 में एक फ़ंक्शन है
पायथन 2 में, exec
एक वाक्य है, विशेष वाक्यविन्यास के साथ: exec code [in globals[, locals]].
अजगर में 3 exec
: अब एक समारोह है exec(code, [, globals[, locals]])
, और अजगर 2 वाक्य रचना एक बढ़ा देंगे SyntaxError
।
चूंकि print
को एक फ़ंक्शन में बयान से बदल दिया गया था, एक __future__
आयात भी जोड़ा गया था। हालाँकि, from __future__ import exec_function
कोई भी नहीं from __future__ import exec_function
, क्योंकि इसकी आवश्यकता नहीं है: पायथन 2 में निष्पादन विवरण को सिंटैक्स के साथ भी इस्तेमाल किया जा सकता है जो बिल्कुल Python 3 में exec
फ़ंक्शन आह्वान की तरह दिखता है। इस प्रकार आप बयान बदल सकते हैं
exec 'code'
exec 'code' in global_vars
exec 'code' in global_vars, local_vars
रूपों के लिए
exec('code')
exec('code', global_vars)
exec('code', global_vars, local_vars)
और बाद के रूपों को पायथन 2 और पायथन 3 दोनों में पहचान के रूप में काम करने की गारंटी है।
पाइथन 2 में हैटैट फंक्शन बग
पायथन 2 में, जब कोई संपत्ति एक त्रुटि hasattr
, तो hasattr
इस संपत्ति को अनदेखा कर देगा, False
hasattr
।
class A(object):
@property
def get(self):
raise IOError
class B(object):
@property
def get(self):
return 'get in b'
a = A()
b = B()
print 'a hasattr get: ', hasattr(a, 'get')
# output False in Python 2 (fixed, True in Python 3)
print 'b hasattr get', hasattr(b, 'get')
# output True in Python 2 and Python 3
यह बग पायथन 3 में तय किया गया है। इसलिए यदि आप पायथन 2 का उपयोग करते हैं, तो उपयोग करें
try:
a.get
except AttributeError:
print("no get property!")
या इसके बजाय getattr
उपयोग करें
p = getattr(a, "get", None)
if p is not None:
print(p)
else:
print("no get property!")
नामांकित मॉड्यूल
मानक पुस्तकालय में कुछ मॉड्यूल का नाम बदल दिया गया है:
पुराना नाम | नया नाम |
---|---|
_winreg | winreg |
ConfigParser | configparser |
copy_reg | copyreg |
पंक्ति | पंक्ति |
SocketServer | socketserver |
_markupbase | markupbase |
रेपर | reprlib |
test.test_support | test.support |
Tkinter | tkinter |
tkFileDialog | tkinter.filedialog |
urllib / urllib2 | urllib, urllib.parse, urllib.error, urllib.response, urllib.request, urllib.robotparser |
कुछ मॉड्यूल को फ़ाइलों से पुस्तकालयों में भी बदल दिया गया है। उदाहरण के रूप में ऊपर से टिंकर और यूरलिब लें।
अनुकूलता
जब पायथन 2.x और 3.x दोनों संस्करणों के बीच संगतता बनाए रखते हैं, तो आप पायथन 2.x संस्करणों पर पायथन 3.x नामों के साथ शीर्ष-स्तरीय मानक लाइब्रेरी पैकेज आयात करने में सक्षम करने के लिए future
बाहरी पैकेज का उपयोग कर सकते हैं।
अष्टक नक्षत्र
पायथन 2 में, एक अष्टक शाब्दिक के रूप में परिभाषित किया जा सकता है
>>> 0755 # only Python 2
क्रॉस-संगतता सुनिश्चित करने के लिए, उपयोग करें
0o755 # both Python 2 and Python 3
पायथन 3 में सभी कक्षाएं "नई शैली की कक्षाएं" हैं।
पायथन 3.x
सभी वर्ग नई शैली की कक्षाएं हैं ; जब एक नए वर्ग अजगर को परिभाषित करते हुए स्पष्ट रूप से यह object
से विरासत में मिलता object
। जैसे, class
परिभाषा में object
निर्दिष्ट करना पूरी तरह से वैकल्पिक है:
class X: pass
class Y(object): pass
इन दोनों वर्गों में अब उनके mro
(विधि संकल्प क्रम) में object
शामिल हैं:
>>> X.__mro__
(__main__.X, object)
>>> Y.__mro__
(__main__.Y, object)
पायथन में 2.x
कक्षाएं डिफ़ॉल्ट रूप से, पुरानी शैली की कक्षाएं हैं; वे object
से अंतर्निहित नहीं हैं। इसके आधार पर वर्गों के शब्दार्थ भिन्न होते हैं यदि हम स्पष्ट रूप से आधार class
रूप में object
जोड़ते हैं:
class X: pass
class Y(object): pass
इस स्थिति में, यदि हम Y
के __mro__
को प्रिंट करने का प्रयास करते हैं, तो पायथन 3.x
मामले में समान आउटपुट दिखाई देगा:
>>> Y.__mro__
(<class '__main__.Y'>, <type 'object'>)
ऐसा इसलिए होता है क्योंकि हमने इसे परिभाषित करते समय ऑब्जेक्ट से स्पष्ट रूप से Y
वारिस बनाया था: class Y(object): pass
। X
कक्षा के लिए जो वस्तु से विरासत में नहीं __mro__
विशेषता मौजूद नहीं है, इसे एक्सेस करने की कोशिश करने से एक AttributeError
में परिणाम होता है।
पायथन के दोनों संस्करणों के बीच संगतता सुनिश्चित करने के लिए, कक्षाओं को आधार वर्ग के रूप में object
साथ परिभाषित किया जा सकता है:
class mycls(object):
"""I am fully compatible with Python 2/3"""
वैकल्पिक रूप से, यदि __metaclass__
वैरिएबल को वैश्विक दायरे में type
करने के लिए सेट किया गया है, तो किसी दिए गए मॉड्यूल में सभी बाद में परिभाषित कक्षाएं स्पष्ट रूप से object
से विरासत में लेने की आवश्यकता के बिना नई शैली हैं:
__metaclass__ = type
class mycls:
"""I am also fully compatible with Python 2/3"""
हटाए गए ऑपरेटरों <> और ``, का पर्यायवाची! = और repr ()
पायथन 2 में, <>
एक पर्यायवाची है !=
इसी तरह `foo`
repr(foo)
पर्याय है।
>>> 1 <> 2
True
>>> 1 <> 1
False
>>> foo = 'hello world'
>>> repr(foo)
"'hello world'"
>>> `foo`
"'hello world'"
>>> 1 <> 2
File "<stdin>", line 1
1 <> 2
^
SyntaxError: invalid syntax
>>> `foo`
File "<stdin>", line 1
`foo`
^
SyntaxError: invalid syntax
सांकेतिक शब्दों में बदलना / व्याख्या करना अब उपलब्ध नहीं है
"1deadbeef3".decode('hex')
# Out: '\x1d\xea\xdb\xee\xf3'
'\x1d\xea\xdb\xee\xf3'.encode('hex')
# Out: 1deadbeef3
"1deadbeef3".decode('hex')
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: 'str' object has no attribute 'decode'
b"1deadbeef3".decode('hex')
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# LookupError: 'hex' is not a text encoding; use codecs.decode() to handle arbitrary codecs
'\x1d\xea\xdb\xee\xf3'.encode('hex')
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# LookupError: 'hex' is not a text encoding; use codecs.encode() to handle arbitrary codecs
b'\x1d\xea\xdb\xee\xf3'.encode('hex')
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AttributeError: 'bytes' object has no attribute 'encode'
हालाँकि, त्रुटि संदेश द्वारा सुझाए गए अनुसार, आप उसी परिणाम को प्राप्त करने के लिए codecs
मॉड्यूल का उपयोग कर सकते हैं:
import codecs
codecs.decode('1deadbeef4', 'hex')
# Out: b'\x1d\xea\xdb\xee\xf4'
codecs.encode(b'\x1d\xea\xdb\xee\xf4', 'hex')
# Out: b'1deadbeef4'
ध्यान दें कि codecs.encode
एक bytes
ऑब्जेक्ट देता है। प्राप्त करने के लिए एक str
वस्तु सिर्फ decode
ASCII करने के लिए:
codecs.encode(b'\x1d\xea\xdb\xee\xff', 'hex').decode('ascii')
# Out: '1deadbeeff'
अजगर 3 में हटाए गए cmp फ़ंक्शन
पायथन 3 में cmp
निर्मित फंक्शन को हटा दिया गया था, साथ में __cmp__
विशेष विधि।
प्रलेखन से:
cmp()
फ़ंक्शन को चला गया माना जाना चाहिए, और__cmp__()
विशेष विधि अब समर्थित नहीं है। छँटाई के लिए__lt__()
उपयोग करें,__eq__()
__hash__()
, और आवश्यकतानुसार अन्य समृद्ध तुलनाओं के साथ। (यदि आपको वास्तव मेंcmp()
कार्यक्षमता की आवश्यकता है, तो आपcmp(a, b)
के बराबर के रूप में अभिव्यक्ति(a > b) - (a < b)
उपयोग कर सकते हैं।
इसके अलावा सभी अंतर्निहित फ़ंक्शन जो कि cmp
पैरामीटर को स्वीकार करते हैं, अब केवल key
कीवर्ड को केवल पैरामीटर स्वीकार करते हैं।
में functools
मॉड्यूल वहाँ भी उपयोगी समारोह cmp_to_key(func)
यदि आप एक से कन्वर्ट करने के लिए अनुमति देता है कि cmp
शैली समारोह एक को key
शैली समारोह:
एक पुरानी शैली की तुलना फ़ंक्शन को एक महत्वपूर्ण फ़ंक्शन में बदलना। प्रमुख कार्यों को स्वीकार करने वाले औजारों के साथ उपयोग किया जाता है (जैसे
sorted()
,min()
,min()
,max()
,heapq.nlargest()
,heapq.nsmallest()
,itertools.groupby()
)। यह फ़ंक्शन मुख्य रूप से पायथन 2 से परिवर्तित होने वाले कार्यक्रमों के लिए एक संक्रमण उपकरण के रूप में उपयोग किया जाता है जिसने तुलनात्मक कार्यों के उपयोग का समर्थन किया है।
सूची समझ में लीक चर
x = 'hello world!'
vowels = [x for x in 'AEIOU']
print (vowels)
# Out: ['A', 'E', 'I', 'O', 'U']
print(x)
# Out: 'U'
x = 'hello world!'
vowels = [x for x in 'AEIOU']
print (vowels)
# Out: ['A', 'E', 'I', 'O', 'U']
print(x)
# Out: 'hello world!'
जैसा कि उदाहरण से देखा जा सकता है, पायथन 2 में x
का मान लीक हो गया था: इसने hello world!
मास्क कर दिया hello world!
और U
प्रिंट किया गया, क्योंकि लूप के समाप्त होने के बाद यह x
का अंतिम मान था।
हालांकि, पायथन 3 x
में मूल रूप से परिभाषित hello world!
प्रिंट करता hello world!
, क्योंकि सूची समझ से स्थानीय चर आसपास के दायरे से चर चर नहीं करता है।
इसके अतिरिक्त, न तो जनरेटर के भाव (2.5 के बाद से पायथन में उपलब्ध) और न ही शब्दकोश या सेट की समझ (जो पायथन 3 से पायथन 2.7 में वापस आ गए थे) पायथन 2 में रिसाव चर।
ध्यान दें कि पायथन 2 और पायथन 3 दोनों में, लूप के लिए उपयोग करते समय चर आसपास के दायरे में लीक हो जाएंगे:
x = 'hello world!'
vowels = []
for x in 'AEIOU':
vowels.append(x)
print(x)
# Out: 'U'
नक्शा()
map()
एक बिलिन है जो एक चलने के तत्वों के लिए एक फ़ंक्शन को लागू करने के लिए उपयोगी है। पायथन 2 में, map
एक सूची देता है। पायथन 3 में, map
एक मैप ऑब्जेक्ट देता है, जो एक जनरेटर है।
# Python 2.X
>>> map(str, [1, 2, 3, 4, 5])
['1', '2', '3', '4', '5']
>>> type(_)
>>> <class 'list'>
# Python 3.X
>>> map(str, [1, 2, 3, 4, 5])
<map object at 0x*>
>>> type(_)
<class 'map'>
# We need to apply map again because we "consumed" the previous map....
>>> map(str, [1, 2, 3, 4, 5])
>>> list(_)
['1', '2', '3', '4', '5']
पायथन 2 में, आप पहचान समारोह के रूप में सेवा करने के लिए None
पास None
कर सकते। यह अब पायथन 3 में काम नहीं करता है।
>>> map(None, [0, 1, 2, 3, 0, 4])
[0, 1, 2, 3, 0, 4]
>>> list(map(None, [0, 1, 2, 3, 0, 5]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
इसके अलावा, पायथन 2 में तर्क के रूप में एक से अधिक चलने योग्य होने पर, map
छोटे itertools.izip_longest
को None
साथ None
itertools.izip_longest
( itertools.izip_longest
समान)। पायथन 3 में, पुनरावृति सबसे कम चलने के बाद बंद हो जाती है।
पायथन 2 में:
>>> map(None, [1, 2, 3], [1, 2], [1, 2, 3, 4, 5])
[(1, 1, 1), (2, 2, 2), (3, None, 3), (None, None, 4), (None, None, 5)]
पायथन 3 में:
>>> list(map(lambda x, y, z: (x, y, z), [1, 2, 3], [1, 2], [1, 2, 3, 4, 5]))
[(1, 1, 1), (2, 2, 2)]
# to obtain the same padding as in Python 2 use zip_longest from itertools
>>> import itertools
>>> list(itertools.zip_longest([1, 2, 3], [1, 2], [1, 2, 3, 4, 5]))
[(1, 1, 1), (2, 2, 2), (3, None, 3), (None, None, 4), (None, None, 5)]
नोट : map
बजाय सूची समझ का उपयोग करने पर विचार करें, जो कि पायथन 2/3 संगत हैं। map(str, [1, 2, 3, 4, 5])
बदलना map(str, [1, 2, 3, 4, 5])
:
>>> [str(i) for i in [1, 2, 3, 4, 5]]
['1', '2', '3', '4', '5']
फ़िल्टर (), मानचित्र () और ज़िप () क्रम के बजाय पुनरावृत्तियाँ लौटाते हैं
पायथन 2 filter
, map
और zip
बिल्ट-इन फ़ंक्शन एक अनुक्रम लौटाते हैं। map
और zip
हमेशा एक सूची देते हैं जबकि filter
के साथ रिटर्न प्रकार दिए गए पैरामीटर के प्रकार पर निर्भर करता है:
>>> s = filter(lambda x: x.isalpha(), 'a1b2c3')
>>> s
'abc'
>>> s = map(lambda x: x * x, [0, 1, 2])
>>> s
[0, 1, 4]
>>> s = zip([0, 1, 2], [3, 4, 5])
>>> s
[(0, 3), (1, 4), (2, 5)]
इसके बजाय पायथन 3 filter
, map
और zip
रिटर्न इट्रेटर में:
>>> it = filter(lambda x: x.isalpha(), 'a1b2c3')
>>> it
<filter object at 0x00000098A55C2518>
>>> ''.join(it)
'abc'
>>> it = map(lambda x: x * x, [0, 1, 2])
>>> it
<map object at 0x000000E0763C2D30>
>>> list(it)
[0, 1, 4]
>>> it = zip([0, 1, 2], [3, 4, 5])
>>> it
<zip object at 0x000000E0763C52C8>
>>> list(it)
[(0, 3), (1, 4), (2, 5)]
अजगर 2 के बाद से itertools.izip
अजगर 3 के बराबर है zip
izip
अजगर 3 पर हटा दिया गया है।
निरपेक्ष / सापेक्ष आयात
पायथन 3 में, PEP 404 ने पायथन 2 से आयात के काम करने के तरीके को बदल दिया है। पैकेजों में निहित सापेक्ष आयात की अनुमति नहीं है और from ... import *
आयात केवल मॉड्यूल स्तर कोड में अनुमत हैं।
अजगर 2 में पायथन 3 व्यवहार को प्राप्त करने के लिए:
- पूर्ण आयात सुविधा
from __future__ import absolute_import
सक्षम की जा सकती है - स्पष्ट सापेक्ष आयातों को निहित सापेक्ष आयातों के स्थान पर प्रोत्साहित किया जाता है
स्पष्टीकरण के लिए, पायथन 2 में, एक मॉड्यूल उसी निर्देशिका में स्थित एक अन्य मॉड्यूल की सामग्री को निम्नानुसार आयात कर सकता है:
import foo
ध्यान दें कि foo
का स्थान अकेले आयात विवरण से अस्पष्ट है। इस प्रकार के निहित सापेक्ष आयात इस प्रकार स्पष्ट सापेक्ष आयातों के पक्ष में हतोत्साहित करते हैं, जो निम्नलिखित की तरह दिखते हैं:
from .moduleY import spam
from .moduleY import spam as ham
from . import moduleY
from ..subpackage1 import moduleY
from ..subpackage2.moduleZ import eggs
from ..moduleA import foo
from ...package import bar
from ...sys import path
बिंदी .
निर्देशिका ट्री के भीतर मॉड्यूल स्थान की स्पष्ट घोषणा की अनुमति देता है।
सापेक्ष आयात पर अधिक
कुछ उपयोगकर्ता परिभाषित पैकेज पर विचार करें जिन्हें shapes
कहा जाता shapes
। निर्देशिका संरचना इस प्रकार है:
shapes
├── __init__.py
|
├── circle.py
|
├── square.py
|
└── triangle.py
circle.py
, square.py
और triangle.py
सब आयात util.py
। वे एक ही स्तर में एक मॉड्यूल का उल्लेख कैसे करेंगे?
from . import util # use util.PI, util.sq(x), etc
या
from .util import * #use PI, sq(x), etc to call functions
द .
समान स्तर के सापेक्ष आयात के लिए उपयोग किया जाता है।
अब, shapes
मॉड्यूल के एक वैकल्पिक लेआउट पर विचार करें:
shapes
├── __init__.py
|
├── circle
│ ├── __init__.py
│ └── circle.py
|
├── square
│ ├── __init__.py
│ └── square.py
|
├── triangle
│ ├── __init__.py
│ ├── triangle.py
|
└── util.py
अब, ये 3 वर्ग कैसे उपयोग करने के लिए संदर्भित करेंगे?
from .. import util # use util.PI, util.sq(x), etc
या
from ..util import * # use PI, sq(x), etc to call functions
..
अभिभावक स्तर रिश्तेदार के आयात के लिए प्रयोग किया जाता है। और जोड़ें .
माता-पिता और बच्चे के बीच स्तरों की संख्या के साथ।
फ़ाइल I / O
file
नहीं रह गया है 3.x (में अंतर्निहित नाम है open
अभी भी काम करता है)।
फ़ाइल I / O का आंतरिक विवरण मानक पुस्तकालय io
मॉड्यूल में स्थानांतरित कर दिया गया है, जो StringIO
का नया घर भी है:
import io
assert io.open is open # the builtin is an alias
buffer = io.StringIO()
buffer.write('hello, ') # returns number of characters written
buffer.write('world!\n')
buffer.getvalue() # 'hello, world!\n'
फ़ाइल मोड (पाठ बनाम बाइनरी) अब एक फ़ाइल को पढ़कर उत्पादित डेटा के प्रकार को निर्धारित करता है (और लिखने के लिए आवश्यक प्रकार):
with open('data.txt') as f:
first_line = next(f)
assert type(first_line) is str
with open('data.bin', 'rb') as f:
first_kb = f.read(1024)
assert type(first_kb) is bytes
पाठ फ़ाइलों के लिए एन्कोडिंग locale.getpreferredencoding(False)
द्वारा लौटाया जाता है। एन्कोडिंग को स्पष्ट रूप से निर्दिष्ट करने के लिए, encoding
कीवर्ड पैरामीटर का उपयोग करें:
with open('old_japanese_poetry.txt', 'shift_jis') as text:
haiku = text.read()
राउंड () फ़ंक्शन टाई-ब्रेकिंग और रिटर्न प्रकार
दौर () टाई ब्रेकिंग
पायथन 2 में, दो पूर्णांकों के समतुल्य रूप से एक संख्या पर round()
का उपयोग करते हुए 0. से उदाहरण के लिए एक सबसे पीछे लौटा जाएगा:
round(1.5) # Out: 2.0
round(0.5) # Out: 1.0
round(-0.5) # Out: -1.0
round(-1.5) # Out: -2.0
पाइथन 3 में, round()
सम पूर्णांक (उर्फ बैंकर्स राउंडिंग ) लौटाएगा। उदाहरण के लिए:
round(1.5) # Out: 2
round(0.5) # Out: 0
round(-0.5) # Out: 0
round(-1.5) # Out: -2
राउंड () फ़ंक्शन आधी से आधी राउंडिंग रणनीति का अनुसरण करता है जो कि अर्ध-सम संख्याओं को निकटतम सम सम पूर्णांक तक ले जाएगा (उदाहरण के लिए, round(2.5)
अब 3.0 के बजाय 2 रिटर्न करता है)।
विकिपीडिया के संदर्भ में , यह निष्पक्ष गोलाई , अभिसारी गोलाई , सांख्यिकीविद की गोलाई , डच गोलाई , गौसियन गोलाई या विषम-सम गोलाई के रूप में भी जाना जाता है।
आधी से भी गोलाई IEEE 754 मानक का हिस्सा है और यह Microsoft के .NET में डिफ़ॉल्ट राउंडिंग मोड भी है।
यह गोलाई रणनीति कुल गोलाई त्रुटि को कम करती है। चूँकि औसतन संख्याओं की संख्या को गोल किया जाता है, वही संख्याएँ हैं जिनकी संख्याएँ नीचे की ओर हैं, गोलाई की त्रुटियाँ रद्द हो जाती हैं। इसके बजाय अन्य गोलाई विधि औसत त्रुटि में ऊपर या नीचे की ओर पूर्वाग्रह रखते हैं।
दौर () वापसी प्रकार
round()
फ़ंक्शन पायथन 2.7 में एक float
प्रकार देता है
round(4.8)
# 5.0
पायथन 3.0 से शुरू होकर, यदि दूसरा तर्क (अंकों की संख्या) छोड़ दिया जाता है, तो यह एक int
रिटर्न देता है।
round(4.8)
# 5
सच, गलत और कोई नहीं
पायथन 2 में, True
, False
और None
भी बिल्ट-इन स्थिरांक None
हैं। इसका मतलब है कि उन्हें आश्वस्त करना संभव है।
True, False = False, True
True # False
False # True
आप के साथ ऐसा नहीं कर सकते None
अजगर 2.4 के बाद से।
None = None # SyntaxError: cannot assign to None
पायथन 3 में, True
, False
और None
अब कीवर्ड हैं।
True, False = False, True # SyntaxError: can't assign to keyword
None = None # SyntaxError: can't assign to keyword
किसी फ़ाइल ऑब्जेक्ट पर लिखते समय मान लौटाएँ
पायथन 2 में, फ़ाइल हैंडल पर सीधे लिखना None
लौटाता:
hi = sys.stdout.write('hello world\n')
# Out: hello world
type(hi)
# Out: <type 'NoneType'>
पायथन 3 में, एक हैंडल पर लिखने पर पाठ लिखते समय लिखे गए वर्णों की संख्या और बाइट्स द्वारा लिखे गए बाइट्स की संख्या वापस आ जाएगी:
import sys
char_count = sys.stdout.write('hello world 🐍\n')
# Out: hello world 🐍
char_count
# Out: 14
byte_count = sys.stdout.buffer.write(b'hello world \xf0\x9f\x90\x8d\n')
# Out: hello world 🐍
byte_count
# Out: 17
लंबे बनाम इंट
पायथन 2 में, सी ssize_t
से बड़ा कोई भी पूर्णांक long
डेटा प्रकार में परिवर्तित हो जाएगा, जो कि शाब्दिक रूप से L
प्रत्यय द्वारा इंगित किया गया है। उदाहरण के लिए, पायथन के 32 बिट बिल्ड पर:
>>> 2**31
2147483648L
>>> type(2**31)
<type 'long'>
>>> 2**30
1073741824
>>> type(2**30)
<type 'int'>
>>> 2**31 - 1 # 2**31 is long and long - int is long
2147483647L
हालाँकि, पायथन 3 में, long
डेटा प्रकार को हटा दिया गया था; कोई फर्क नहीं पड़ता कि पूर्णांक कितना बड़ा है, यह एक int
।
2**1024
# Output: 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216
print(-(2**1024))
# Output: -179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216
type(2**1024)
# Output: <class 'int'>
क्लास बूलियन मान
पायथन 2 में, यदि आप अपने द्वारा एक वर्ग बूलियन मान को परिभाषित करना चाहते हैं, तो आपको अपनी कक्षा पर __nonzero__
विधि लागू करने की आवश्यकता है। मान डिफ़ॉल्ट रूप से सही है।
class MyClass:
def __nonzero__(self):
return False
my_instance = MyClass()
print bool(MyClass) # True
print bool(my_instance) # False
अजगर 3 में, __bool__
के बजाय प्रयोग किया जाता है __nonzero__
class MyClass:
def __bool__(self):
return False
my_instance = MyClass()
print(bool(MyClass)) # True
print(bool(my_instance)) # False