2010-08-06 23 views
11

में कनवर्ट करने के लिए तैयार हो रहा है जैसा कि हम सभी अब जानते हैं (मुझे उम्मीद है), पायथन 3 धीरे-धीरे पाइथन 2.x को प्रतिस्थापित करना शुरू कर रहा है। बेशक यह मौजूदा कई कोडों को आखिरकार पोर्ट करने से पहले कई वर्षों तक होगा, लेकिन स्विच को आसान बनाने के लिए हम अपने संस्करण 2.x कोड में अभी कुछ कर सकते हैं।पायथन 2.x से 3.x

स्पष्ट रूप से 3.x में what's new पर एक नज़र डालने में मदद मिलेगी, लेकिन आने वाली रूपांतरण को और अधिक दर्द रहित बनाने के लिए हम कुछ चीजें क्या कर सकते हैं (साथ ही यदि आवश्यक हो तो समवर्ती संस्करणों के अपडेट आउटपुट करना आसान बनाता है)? मैं विशेष रूप से लाइनों के बारे में सोच रहा हूं, हम अपनी स्क्रिप्ट को बंद कर सकते हैं जिससे पाइथन के पुराने संस्करण 3.x के समान होंगे, हालांकि अन्य आदतों का भी स्वागत है।

सबसे स्पष्ट कोड स्क्रिप्ट है कि मैं के बारे में सोच सकते हैं के शीर्ष में जोड़ने के लिए है:

from __future__ import division 
from __future__ import print_function 
try: 
    range = xrange 
except NameError: 
    pass 

सबसे स्पष्ट आदत बात मैं के बारे में सोच सकते हैं स्ट्रिंग प्रारूपण के लिए "{0} {1}!".format("Hello", "World") है।

कोई अन्य लाइनें और अच्छी आदतें पाने के लिए?

उत्तर

12

सबसे बड़ी समस्या जिसे माइक्रो-स्तरीय परिवर्तनों और 2to3 द्वारा पर्याप्त रूप से संबोधित नहीं किया जा सकता है, का परिवर्तन है बाइट्स से यूनिकोड तक डिफ़ॉल्ट स्ट्रिंग प्रकार।

यदि आपके कोड को एन्कोडिंग और बाइट I/O के साथ कुछ भी करने की ज़रूरत है, तो इसे सही ढंग से परिवर्तित करने के लिए मैन्युअल प्रयासों की एक गुच्छा की आवश्यकता होगी, ताकि बाइट्स होने वाली चीजें बाइट्स रहें, और दाईं ओर उचित तरीके से डीकोड की गई हो मंच। आप पाएंगे कि कुछ स्ट्रिंग विधियां (विशेष रूप से format()) और लाइब्रेरी कॉलों को यूनिकोड स्ट्रिंग की आवश्यकता होती है, इसलिए आपको यूनिकोड के रूप में तारों का उपयोग करने के लिए अतिरिक्त डिकोड/एन्कोड चक्र की आवश्यकता हो सकती है, भले ही वे वास्तव में केवल बाइट्स हों।

यह इस तथ्य से मदद नहीं करता है कि कुछ पायथन मानक लाइब्रेरी मॉड्यूल को बाइट्स/यूनिकोड/एन्कोडिंग समस्याओं पर उचित ध्यान दिए बिना 2to3 का उपयोग करके क्रूडली रूप से परिवर्तित किया गया है, और इसलिए स्वयं स्ट्रिंग प्रकार उचित है इसके बारे में गलतियां करते हैं। इनमें से कुछ को बाहर निकाल दिया जा रहा है, लेकिन कम से कम पायथन 3.0 से 3.2 तक आपको परेशान और संभावित रूप से बग्गी व्यवहार का सामना करना पड़ेगा जैसे urllib, ईमेल और wsgiref जिन्हें बाइट एन्कोडिंग के बारे में जानने की आवश्यकता है।

हर बार जब आप स्ट्रिंग अक्षर लिखते हैं तो सावधान रहकर आप समस्या को सुधार सकते हैं। u'' स्ट्रिंग्स जो किसी भी चीज के लिए मूल रूप से वर्ण-आधारित, b'' स्ट्रिंग्स जो वास्तव में बाइट्स है, और '' 'डिफ़ॉल्ट स्ट्रिंग' प्रकार के लिए स्ट्रिंग्स का उपयोग करें, जहां इससे कोई फर्क नहीं पड़ता है या आपको लाइब्रेरी कॉल की स्ट्रिंग उपयोग आवश्यकताओं से मेल खाना आवश्यक है।

दुर्भाग्यवश b'' सिंटैक्स केवल पायथन 2.6 में पेश किया गया था, इसलिए यह पिछले संस्करणों के उपयोगकर्ताओं को बंद कर देता है।

ईटा:

क्या अंतर है?

ओह मेरा। कुंआ...

एक बाइट में 0-255 की सीमा में एक मान होता है, और बाइनरी डेटा (उदाहरण के लिए एक छवि की सामग्री) या कुछ पाठ का प्रतिनिधित्व कर सकता है, इस मामले में एक मानक चुना जाना चाहिए कि कैसे उन बाइट्स में वर्णों का एक सेट मैप करें। इनमें से अधिकतर 'एन्कोडिंग' मानक सामान्य 'ASCII' वर्ण को उसी तरह बाइट 0-127 में सेट करते हैं, इसलिए आमतौर पर पाइथन 2 में ASCII- केवल पाठ प्रसंस्करण के लिए बाइट स्ट्रिंग का उपयोग करना सुरक्षित है।

यदि आप बाइट स्ट्रिंग में ASCII सेट के बाहर के किसी भी वर्ण का उपयोग करना चाहते हैं, आप परेशानी में हैं, क्योंकि प्रत्येक एन्कोडिंग शेष बाइट मान 128-255 में वर्णों का एक अलग सेट मैप करता है, और अधिकांश एन्कोडिंग प्रत्येक संभावित चरित्र को मानचित्र नहीं दे सकते बाइट्स के लिए। यह उन सभी समस्याओं का स्रोत है जहां आप एक लोकेल से एक फ़ाइल को एक अन्य लोकेल में एक विंडोज ऐप में लोड करते हैं और सभी उच्चारण या गैर-लैटिन अक्षरों को गलत तरीके से बदलते हैं, जो एक अपठनीय गड़बड़ बनाते हैं। (उर्फ 'मोजिबैक')

'मल्टीबाइट' एन्कोडिंग भी हैं, जो प्रत्येक चरित्र को स्टोर करने के लिए एक से अधिक बाइट का उपयोग करके उपलब्ध स्थान में अधिक वर्ण फिट करने का प्रयास करते हैं। ये पूर्वी एशियाई लोकेशंस के लिए पेश किए गए थे, क्योंकि बहुत सारे चीनी पात्र हैं। लेकिन यूटीएफ -8 भी एक बेहतर डिज़ाइन किया गया आधुनिक मल्टीबाइट एन्कोडिंग है जो प्रत्येक चरित्र को समायोजित कर सकता है।

यदि आप मल्टीबाइट एन्कोडिंग में बाइट स्ट्रिंग पर काम कर रहे हैं- और आज आप शायद होंगे, क्योंकि यूटीएफ -8 का व्यापक रूप से उपयोग किया जाता है; वास्तव में, किसी आधुनिक एप्लिकेशन में कोई अन्य एन्कोडिंग का उपयोग नहीं किया जाना चाहिए-फिर आपको यह पता लगाने की तुलना में और भी अधिक समस्याएं मिलती हैं कि आप किस एन्कोडिंग के साथ खेल रहे हैं। len() आपको बाइट्स में लंबाई बताएगा, वर्णों की लंबाई नहीं, और यदि आप बाइट्स को अनुक्रमणित करना और बदलना शुरू करते हैं तो आप दो में एक मल्टीबाइट अनुक्रम तोड़ने की संभावना रखते हैं, एक अमान्य अनुक्रम उत्पन्न करते हैं और आम तौर पर सब कुछ भ्रमित करते हैं।

इस कारण से, पायथन 1.6 और बाद में मूल यूनिकोड तार (वर्तनी u'something') है, जहां स्ट्रिंग में प्रत्येक इकाई एक चरित्र है, बाइट नहीं है। आप len() उन्हें, टुकड़ा कर सकते हैं, उन्हें प्रतिस्थापित कर सकते हैं, उन्हें regex कर सकते हैं, और वे हमेशा उचित व्यवहार करेंगे। टेक्स्ट प्रसंस्करण कार्यों के लिए वे अनिवार्य रूप से बेहतर हैं, यही कारण है कि पायथन 3 उन्हें डिफ़ॉल्ट स्ट्रिंग प्रकार बनाता है ('' से पहले u डालने के बिना)।

पकड़ यह है कि विंडोज़, या HTTP, या एसएमटीपी के अलावा ओएस पर फ़ाइल नाम जैसे कई मौजूदा इंटरफेस मुख्य रूप से बाइट-आधारित हैं, जो एन्कोडिंग निर्दिष्ट करने के एक अलग तरीके से हैं। तो जब आप उन घटकों से निपट रहे हैं जिन्हें बाइट्स की आवश्यकता है तो आपको अपने यूनिकोड तारों को सही ढंग से बाइट्स पर एन्कोड करने की देखभाल करनी होगी, और पायथन 3 में आपको इसे कुछ स्थानों पर स्पष्ट रूप से करना होगा जहां आपको पहले आवश्यकता नहीं थी।

यह एक आंतरिक कार्यान्वयन विस्तार है कि यूनिकोड स्ट्रिंग आंतरिक रूप से प्रति इकाई भंडारण के 'दो बाइट' लेते हैं। आप उस भंडारण को कभी नहीं देख पाएंगे; आपको बाइट्स के मामले में इसके बारे में नहीं सोचना चाहिए। जिन इकाइयों पर आप काम कर रहे हैं वे अवधारणात्मक पात्र हैं, इस पर ध्यान दिए बिना कि पाइथन स्मृति में उनका प्रतिनिधित्व कैसे करता है।

... एक तरफ:

यह बिल्कुल सही नहीं है। विंडोज निर्माण की तरह पायथन के 'संकीर्ण निर्माण' पर, यूनिकोड स्ट्रिंग की प्रत्येक इकाई तकनीकी रूप से एक चरित्र नहीं है, लेकिन एक यूटीएफ -16 'कोड इकाई' है। बेसिक बहुभाषी विमान के पात्रों के लिए, 0x0000-0xFFFF से आपको कोई फर्क नहीं दिखाई देगा, लेकिन यदि आप इस 16-बिट रेंज के बाहर से वर्णों का उपयोग कर रहे हैं, तो 'एस्ट्रल प्लेन' में, आप पाएंगे कि वे एक के बजाय दो इकाइयां, और फिर, जब आप उन्हें टुकड़ा करते हैं तो आप एक चरित्र को विभाजित करने का जोखिम लेते हैं।

यह बहुत खराब है, और ऐसा इसलिए हुआ है क्योंकि विंडोज (और जावा जैसे अन्य) यूटीएफ -16 पर एक स्मृति मेमोरी स्टोरेज तंत्र के रूप में बस गए हैं, इससे पहले यूनिकोड 65,000-वर्ण सीमा से अधिक हो गया था।हालांकि, इन विस्तारित वर्णों का उपयोग अभी भी बहुत दुर्लभ है, और विंडोज़ पर किसी भी व्यक्ति को उनके लिए कई अनुप्रयोगों में तोड़ने के लिए उपयोग किया जाएगा, इसलिए यह आपके लिए महत्वपूर्ण नहीं है।

'विस्तृत बिल्ड' पर, यूनिकोड तार वास्तविक चरित्र 'कोड पॉइंट' इकाइयों से बने होते हैं, इसलिए बीएमपी के बाहर विस्तारित वर्ण भी लगातार और आसानी से संभाले जा सकते हैं। इसके लिए भुगतान करने की कीमत दक्षता है: प्रत्येक स्ट्रिंग इकाई स्मृति में चार बाइट स्टोरेज लेती है।

+0

जब बाइट और यूनिकोड तारों की बात आती है, तो क्या अंतर है? बस उस बाइट स्ट्रिंग्स प्रति बाइट का उपयोग करते हैं जबकि यूनिकोड दो बाइट्स का उपयोग करता है? –

+0

"" "यूटीएफ -8 ... आधुनिक अनुप्रयोग में कोई अन्य एन्कोडिंग का उपयोग नहीं किया जाना चाहिए" जब तक कि आपकी सरकार कुछ और जरूरी नहीं है, उदाहरण के लिए 'gb18030' :-) –

+0

यह बाइट स्ट्रिंग्स और यूनिकोड के बीच के अंतर के बारे में एक * उत्कृष्ट * स्पष्टीकरण था। मैं ASCII बनाम यूनिकोड से कम या ज्यादा परिचित था, लेकिन (जाहिर है) मैं परिचित नहीं था कि पाइथन (एएसपी 3.x) ने उनके साथ कैसे व्यवहार किया। काश मैं एक से अधिक बार वोट दे सकता हूं;) –

5

मैं var1//var2 जैसी चीजों का उपयोग करने की आदत में आने की कोशिश कर रहा हूं जब भी मैं वास्तव में पूर्णांक विभाजन (और एक फ्लोट नहीं) चाहता हूं। पाइथन 3 की ओर एक बड़ा कदम नहीं है, लेकिन कम से कम मुझे वापस जाना होगा और मेरे सभी डिवीजनों की जांच नहीं करनी होगी :)

संबंधित मुद्दे