अजगर में स्ट्रिंग द्वारा यूनिकोड की घोषणा क्यों?


122

मैं अभी भी अजगर सीख रहा हूं और मुझे संदेह है:

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

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

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

a = "A normal string without declared Unicode"

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

a = u"A string with declared Unicode"

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

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


6
# coding: utf8पर्याप्त है, के लिए कोई ज़रूरत नहीं है-*-
जेलीफ़िश

1
@ जेलीफ़िश मुझे लगता है कि आप टाइप करना चाहते थे # coding: utf-8
सैमुअल हैमर

होना चाहिए #coding=utf-8python.org/dev/peps/pep-0263
शेन

जवाबों:


167

वे दो अलग-अलग चीजें हैं, जैसा कि दूसरों ने उल्लेख किया है।

जब आप निर्दिष्ट करते हैं# -*- 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सामने एक निर्दिष्ट करने की आवश्यकता है (जैसे b'These are bytes', बाइट्स के अनुक्रम को घोषित करने के लिए)।


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

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

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

@ मर्क: ASCII सुधार के लिए धन्यवाद; मैंने जल्दी से PEP ( python.org/dev/peps/pep-0263 ) को स्किम किया और यह प्रस्तावना में लैटिन -1 के बारे में बात करता है। मुझे नहीं लगता कि आपकी फ़ाइल के अधिकांश मामलों में उच्च यूनिकोड वर्णों को एम्बेड करना एक महान विचार है। निश्चित रूप से, यदि आप अपने स्रोत फ़ाइल में बहुत सारे गैर-अंग्रेज़ी स्ट्रिंग को कोड कर रहे हैं, तो यह आसान बना सकता है, लेकिन आप आम तौर पर उपयोगकर्ता के लिए प्रदर्शन के लिए ऐसा करते हैं, और आपको उन लोगों को किसी भी स्थान पर वैसे भी परिभाषित करना चाहिए। और एक एकल गलत पाठ संपादक उन सभी पात्रों को भ्रष्ट कर सकता है।
क्रिस बी।

4
सहमत हैं यदि आप एक i18nalized ऐप प्रोग्रामिंग कर रहे हैं, लेकिन विचार करें कि क्या आप एक चीनी या फ्रांसीसी प्रोग्रामर हैं। यह केवल तार नहीं है, बल्कि टिप्पणियां भी हैं। यह महान है कि पायथन स्रोत के एन्कोडिंग के साथ लचीला है। पायथन 3 में चर नामों में गैर- ASCII वर्ण भी हो सकते हैं।
मार्क तोलोनन

23

जैसा कि अन्य लोगों ने कहा है, # 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'

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

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

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

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

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

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

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


10

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


मुझसे तब गलती हुई, मुझे लगा कि वे वही हैं। तो यूनिकोड स्ट्रिंग्स के लिए उपयोग i18n है?
ऑस्कर कारबॉलल

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

7

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

the-हेडर की परिभाषा के बिना पायथन लिपि में a जैसे गैर-अस्की चरित्र डालना एक चेतावनी फेंक देगा

त्रुटि


-1

मैंने निम्नलिखित मॉड्यूल को यूनिकोड कहा है जो चर पर परिवर्तन करने में सक्षम है:

import sys
import os

def ustr(string):

    string = 'u"%s"'%string

    with open('_unicoder.py', 'w') as script:

        script.write('# -*- coding: utf-8 -*-\n')
        script.write('_ustr = %s'%string)

    import _unicoder
    value = _unicoder._ustr

    del _unicoder
    del sys.modules['_unicoder']

    os.system('del _unicoder.py')
    os.system('del _unicoder.pyc')

    return value

फिर अपने कार्यक्रम में आप निम्न कार्य कर सकते हैं:

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

from unicoder import ustr

txt = 'Hello, Unicode World'
txt = ustr(txt)

print type(txt) # <type 'unicode'>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.