2010-07-03 12 views
98

मैं अभी भी सीख रहा हूँ अजगर और मैं एक संदेह है:क्यों पाइथन में स्ट्रिंग द्वारा यूनिकोड घोषित करें?

अजगर 2.6.x में मैं आमतौर पर एन्कोडिंग फ़ाइल शीर्षक में इस तरह की घोषणा (PEP 0263 में के रूप में)

# -*- coding: utf-8 -*- 

उसके बाद, मेरे तार हमेशा की तरह लिखा जाता है:

a = "A normal string without declared Unicode" 

लेकिन हर मैं एक अजगर परियोजना कोड देखते हैं, एन्कोडिंग हैडर पर घोषित नहीं किया गया है। इसके बजाए, यह इस तरह की प्रत्येक स्ट्रिंग पर घोषित किया गया है:

a = u"A string with declared Unicode" 

क्या अंतर है? इसका उद्देश्य क्या है? मुझे पता है कि Python 2.6.x डिफ़ॉल्ट रूप से ASCII एन्कोडिंग सेट करता है, लेकिन इसे हेडर घोषणा द्वारा ओवरराइड किया जा सकता है, तो प्रति स्ट्रिंग घोषणा का बिंदु क्या है?

परिशिष्ट: लगता है कि मैं स्ट्रिंग एन्कोडिंग के साथ फ़ाइल एन्कोडिंग को मिलाया गया है। यह समझा के लिए धन्यवाद :)

+4

'# कोडिंग: utf8' काफी अच्छा है,' की कोई आवश्यकता नहीं - * - ' – jellyfish

+0

@jellyfish मुझे लगता है आप' टाइप करने के लिए # कोडिंग का मतलब: utf -8'। –

+0

'# कोडिंग = utf-8' होना चाहिए। https://www.python.org/dev/peps/pep-0263/ –

उत्तर

141

उन, दो अलग बातें हैं के रूप में दूसरों का उल्लेख किया है फेंक देते हैं।

जब आप # -*- coding: utf-8 -*- निर्दिष्ट करते हैं, आप अजगर को बता रहे हैं आपके द्वारा सहेजे गए स्रोत फ़ाइल utf-8 है। पायथन 2 के लिए डिफ़ॉल्ट ASCII है (पायथन 3 के लिए यह utf-8 है)। यह सिर्फ इस बात को प्रभावित करता है कि दुभाषिया फ़ाइल में वर्णों को कैसे पढ़ता है।

सामान्य में, यह शायद सबसे अच्छा है कि आप अपना फ़ाइल में उच्च यूनिकोड वर्ण एम्बेड करने के लिए कोई बात नहीं क्या एन्कोडिंग है नहीं है; आप स्ट्रिंग यूनिकोड एस्केप का उपयोग कर सकते हैं, जो या तो एन्कोडिंग में काम करते हैं।


जब आप सामने में एक u, u'This is a string' तरह से एक स्ट्रिंग की घोषणा, यह अजगर संकलक कि स्ट्रिंग यूनिकोड, नहीं बाइट्स बताता है। इसे दुभाषिया द्वारा पारदर्शी रूप से संभाला जाता है; सबसे स्पष्ट अंतर यह है कि अब आप स्ट्रिंग में यूनिकोड वर्ण एम्बेड कर सकते हैं (यानी, u'\u2665' अब कानूनी है)। आप इसे डिफ़ॉल्ट बनाने के लिए from __future__ import unicode_literals का उपयोग कर सकते हैं।

यह केवल अजगर 2 के लिए लागू होता है; अजगर 3 में डिफ़ॉल्ट यूनिकोड है, और आप (b'These are bytes' की तरह, बाइट्स की एक दृश्य घोषित करने के लिए) सामने एक b निर्दिष्ट करने के लिए की जरूरत है।

+0

स्पष्टीकरण के लिए धन्यवाद! मैं इसे स्वीकार करने के रूप में सेट करूँगा क्योंकि सबसे पूरा एक है :) –

+2

पायथन 2 के लिए डिफ़ॉल्ट स्रोत एन्कोडिंग ** ascii ** है। –

+23

यह वास्तव में आपके फ़ाइल में उच्च यूनिकोड वर्ण एम्बेड करने का एक अच्छा विचार है। मुझे संदेह है कि गैर-अंग्रेजी बोलने वाले अपने तारों में यूनिकोड भागने को पढ़ना चाहते हैं। –

10

कि तार का प्रारूप निर्धारित नहीं करता है; यह फ़ाइल के प्रारूप को सेट करता है। यहां तक ​​कि उस शीर्षलेख के साथ, "hello" एक बाइट स्ट्रिंग है, न कि यूनिकोड स्ट्रिंग। इसे यूनिकोड बनाने के लिए, आपको हर जगह u"hello" का उपयोग करना होगा। .py फ़ाइल पढ़ने पर हेडर का उपयोग करने के लिए किस प्रारूप का उपयोग करना है इसका एक संकेत है।

+0

तब मुझे गलत लगा, मैंने सोचा कि वे वही थे। तो यूनिकोड तारों के लिए उपयोग i18n है? –

+0

@ ऑस्कर: हाँ, अधिकांश भाग के लिए। यदि आप Django या कुछ के साथ वेबसाइट बना रहे थे और इसे गैर-ASCII वर्णों वाले लोगों को संभालना था, तो यह एक और संभावित उपयोग है। – icktoofay

7

हैडर परिभाषा ही कोड की एन्कोडिंग रनटाइम पर, नहीं जिसके परिणामस्वरूप तार परिभाषित करने के लिए है।

utf-8 हैडर परिभाषा के बिना अजगर स्क्रिप्ट में 2 की तरह एक गैर- ASCII चरित्र डाल एक चेतावनी error http://www.freeimagehosting.net/uploads/1ed15124c4.jpg

+0

गलत त्रुटि, लेकिन हाँ। –

+0

ओह, सही धन्यवाद – ebt

19

के रूप में अन्य लोगों ने कहा, # coding: एन्कोडिंग स्रोत फ़ाइल में सहेजा जाता है निर्दिष्ट करता है।यहाँ कुछ उदाहरण इस वर्णन करने के लिए कर रहे हैं:

cp437 (मेरी एन्कोडिंग कंसोल) के रूप में डिस्क पर सहेजी जाने वाली फ़ाइल है, लेकिन कोई एन्कोडिंग घोषित

b = 'über' 
u = u'über' 
print b,repr(b) 
print u,repr(u) 

आउटपुट:

File "C:\ex.py", line 1 
SyntaxError: Non-ASCII character '\x81' in file C:\ex.py on line 1, but no 
encoding declared; see http://www.python.org/peps/pep-0263.html for details 

# coding: cp437 के साथ फ़ाइल का आउटपुट जोड़ा गया:

über '\x81ber' 
über u'\xfcber' 

पहले, पायथन को एन्कोडिंग नहीं पता था और गैर-ASCII चरित्र के बारे में शिकायत की गई थी। एक बार यह एन्कोडिंग को जानता था, बाइट स्ट्रिंग बाइट्स को मिला जो वास्तव में डिस्क पर थीं। यूनिकोड स्ट्रिंग के लिए, पायथन ने \ x81 पढ़ा, पता था कि सीपी 437 में ü था, और इसे ü के लिए यूनिकोड कोडपॉइंट में डीकोड किया गया जो यू + 00 एफसी है। जब बाइट स्ट्रिंग मुद्रित की गई थी, पायथन ने कंसोल पर हेक्स मान 81 भेजा। जब यूनिकोड स्ट्रिंग मुद्रित की गई थी, तो पायथन ने सीपीयू 437 के रूप में सही ढंग से मेरे कंसोल एन्कोडिंग का पता लगाया और ü के लिए cp437 मान में यूनिकोड ü का अनुवाद किया।

यहाँ एक फ़ाइल की घोषणा की और में सहेजा के साथ होता है UTF-8:

├╝ber '\xc3\xbcber' 
über u'\xfcber' 

UTF-8 में, ü, हेक्स बाइट्स C3 BC के रूप में एन्कोड किया गया है तो बाइट स्ट्रिंग उन बाइट का है , लेकिन यूनिकोड स्ट्रिंग पहले उदाहरण के समान है। पायथन ने दो बाइट्स पढ़े और इसे सही तरीके से डीकोड किया। पायथन ने बाइट स्ट्रिंग को गलत तरीके से मुद्रित किया, क्योंकि उसने दो यूटीएफ -8 बाइट्स को ü को सीधे मेरे सीपी 437 कंसोल पर भेजा।

यहाँ फ़ाइल cp437 घोषित किया जाता है, लेकिन में सहेजा UTF-8:

├╝ber '\xc3\xbcber' 
├╝ber u'\u251c\u255dber' 

बाइट स्ट्रिंग अभी भी डिस्क पर बाइट्स (UTF-8 हेक्स बाइट्स C3 BC) मिल गया है, लेकिन उन्हें दो के रूप में व्याख्या एक यूटीएफ -8-एन्कोडेड चरित्र के बजाय cp437 वर्ण। उन दो पात्रों जहां यूनिकोड कोड बिंदुओं का अनुवाद किया गया है, और सबकुछ गलत तरीके से प्रिंट करता है।

+0

+1 :) –

0

अगर आप अजगर 2 का उपयोग कर रहे हैं, इस जोड़ें: from __future__ import unicode_literals

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