मैंने कुछ py स्क्रिप्ट देखी हैं जो स्क्रिप्ट के शीर्ष पर इसका उपयोग करती हैं। किन मामलों में इसका उपयोग करना चाहिए?
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
मैंने कुछ py स्क्रिप्ट देखी हैं जो स्क्रिप्ट के शीर्ष पर इसका उपयोग करती हैं। किन मामलों में इसका उपयोग करना चाहिए?
import sys
reload(sys)
sys.setdefaultencoding("utf-8")
जवाबों:
दस्तावेज़ीकरण के अनुसार: यह आपको डिफ़ॉल्ट ASCII से दूसरे एन्कोडिंग जैसे UTF-8 पर स्विच करने की अनुमति देता है, जिसे पायथन रनटाइम का उपयोग करेगा जब भी इसे यूनिकोड के लिए एक स्ट्रिंग बफर को डीकोड करना होगा।
यह फ़ंक्शन केवल पायथन स्टार्ट-अप समय पर उपलब्ध है, जब पायथन पर्यावरण को स्कैन करता है। इसे सिस्टम-वाइड मॉड्यूल में बुलाया जाना है sitecustomize.py
, इस मॉड्यूल का मूल्यांकन होने के बाद, setdefaultencoding()
फ़ंक्शन sys
मॉड्यूल से हटा दिया जाता है ।
वास्तव में इसका उपयोग करने का एकमात्र तरीका एक पुनः लोड हैक के साथ है जो विशेषता को वापस लाता है।
इसके अलावा, के उपयोग sys.setdefaultencoding()
को हमेशा हतोत्साहित किया गया है , और यह py3k में एक नो-ऑप बन गया है। Py3k की एन्कोडिंग "utf-8" के लिए हार्ड-वायर्ड है और इसे बदलने से त्रुटि उत्पन्न होती है।
मैं पढ़ने के लिए कुछ संकेत देता हूं:
sys.stdout
None
sys.setdefaultencoding()
हमेशा के लिए उपयोग को हतोत्साहित किया गया"
UTF-8
। LC_ALL=en_US.UTF-8 python3 -c 'import sys; print(sys.stdout.encoding)'
देता है, UTF-8
लेकिन LC_ALL=C python3 -c 'import sys; print(sys.stdout.encoding)'
देता है ANSI_X3.4-1968
(या शायद कुछ और)
जवाब है कभी ! (जब तक आप वास्तव में नहीं जानते कि आप क्या कर रहे हैं)
9/10 बार समाधान को एन्कोडिंग / डिकोडिंग की उचित समझ के साथ हल किया जा सकता है।
1/10 लोगों के पास गलत तरीके से परिभाषित स्थान या वातावरण है और उन्हें सेट करने की आवश्यकता है:
PYTHONIOENCODING="UTF-8"
कंसोल मुद्रण समस्याओं को ठीक करने के लिए उनके वातावरण में।
(पुनः उपयोग से बचने के लिए मारा गया) जब भी पाइथन 2.x को यूनिकोड () को एक स्ट्रेट () और (इसके विपरीत) में परिवर्तित करने की आवश्यकता होती है, तो डिफ़ॉल्ट डिफ़ॉल्ट एन्कोडिंग / डिकोडिंग में परिवर्तन होता है और एन्कोडिंग नहीं दी जाती है। अर्थात:sys.setdefaultencoding("utf-8")
str(u"\u20AC")
unicode("€")
"{}".format(u"\u20AC")
पायथन 2.x में, डिफ़ॉल्ट एन्कोडिंग ASCII पर सेट है और उपरोक्त उदाहरण इसके साथ विफल होंगे:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)
(मेरा कंसोल UTF-8 के रूप में कॉन्फ़िगर किया गया है, इसलिए "€" = '\xe2\x82\xac'
, इस पर अपवाद \xe2
)
या
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)
मुझे मेरे लिए काम करने की अनुमति देगा , लेकिन जरूरी नहीं कि उन लोगों के लिए काम करें जो UTF-8 का उपयोग नहीं करते हैं। ASCII का डिफ़ॉल्ट यह सुनिश्चित करता है कि एन्कोडिंग की मान्यताओं को कोड में बेक नहीं किया गया हैsys.setdefaultencoding("utf-8")
ठीक करने के लिए प्रदर्शित होने का एक साइड इफेक्ट भी है sys.setdefaultencoding("utf-8")
sys.stdout.encoding
, जो कंसोल में वर्णों को प्रिंट करते समय उपयोग किया जाता है। इसे सेट करने के लिए पायथन उपयोगकर्ता के लोकेल (लिनक्स / OS X / Un * x) या कोडपेज (विंडोज) का उपयोग करता है। कभी-कभी, उपयोगकर्ता का स्थान टूट जाता है और बस कंसोल एन्कोडिंगPYTHONIOENCODING
को ठीक करने की आवश्यकता होती है ।
उदाहरण:
$ export LANG=en_GB.gibberish
$ python
>>> import sys
>>> sys.stdout.encoding
'ANSI_X3.4-1968'
>>> print u"\u20AC"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)
>>> exit()
$ PYTHONIOENCODING=UTF-8 python
>>> import sys
>>> sys.stdout.encoding
'UTF-8'
>>> print u"\u20AC"
€
लोग 16 साल से पायथन 2.x के खिलाफ इस समझ के साथ विकसित हो रहे हैं कि डिफ़ॉल्ट एन्कोडिंग ASCII है। UnicodeError
गैर-ASCII में पाए जाने वाले तार पर यूनिकोड रूपांतरण के लिए स्ट्रिंग को संभालने के लिए अपवाद हैंडलिंग तरीके लिखे गए हैं।
से https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/
def welcome_message(byte_string):
try:
return u"%s runs your business" % byte_string
except UnicodeError:
return u"%s runs your business" % unicode(byte_string,
encoding=detect_encoding(byte_string))
print(welcome_message(u"Angstrom (Å®)".encode("latin-1"))
डिफ़ॉल्ट कोडिंग को सेट करने से पहले यह कोड एससीआई एन्कोडिंग में "in" को डिकोड करने में असमर्थ होगा और फिर एन्कोडिंग का अनुमान लगाने के लिए अपवाद हैंडलर में प्रवेश करेगा और इसे ठीक से यूनिकोड में बदल देगा। मुद्रण: Angstrom ()®) आपका व्यवसाय चलाता है। एक बार जब आप डिफेंककोडिंग को utf-8 में सेट करते हैं, तो कोड यह पाएगा कि बाइट_स्ट्रिंग को utf-8 के रूप में व्याख्या किया जा सकता है और इसलिए यह डेटा को मैन्गल करेगा और इसके बजाय इसे लौटाएगा: Angstrom (Ů) आपका व्यवसाय चलाता है।
जो कुछ स्थिर होना चाहिए उसे बदलने से आपके द्वारा निर्भर मॉड्यूल पर नाटकीय प्रभाव पड़ेगा। अपने कोड के अंदर और बाहर आने वाले डेटा को ठीक करना बेहतर है।
जबकि डिफ़ॉल्ट उदाहरण के लिए UTF-8 की सेटिंग निम्नलिखित उदाहरण में मूल कारण नहीं है, यह दिखाता है कि कैसे समस्याएँ मुखौटा होती हैं और कैसे, जब इनपुट एन्कोडिंग में परिवर्तन होता है, तो कोड एक स्पष्ट तरीके से टूट जाता है: यूनिकोडडबलक्रेडर: utf8 'कोडेक स्थिति 3131 में 0 डेक्स बाइट 0x80: अमान्य प्रारंभ बाइट
sys.setdefaultencoding("utf-8")
, कोड को पायथन 3 की तरह व्यवहार करना अच्छा है। यह अब 2017 है। यहां तक कि जब आपने 2015 में जवाब वापस लिखा था, तो मुझे लगता है कि पिछड़े के बजाय आगे देखना बेहतर था। यह वास्तव में मेरे लिए सबसे सरल समाधान था, जब मैंने पाया कि मेरा कोड पायथन 2 में अलग तरह से व्यवहार करता है, इस पर निर्भर करता है कि आउटपुट पुनर्निर्देशित है (पायथन 2 के लिए बहुत बुरा समस्या)। कहने की जरूरत नहीं है, मेरे पास पहले से ही है # coding: utf-8
, और मुझे पायथन 3 के लिए किसी भी वर्कअराउंड की आवश्यकता नहीं है (मुझे वास्तव में setdefaultencoding
उपयोग किए गए संस्करण की जांच करना है)।
sys.setdefaultencoding("utf-8")
आपके Py 2.x कोड को Python 3 के साथ संगत नहीं बनाता है। न ही यह बाहरी मॉड्यूल को ठीक करता है जो मान लेता है कि डिफ़ॉल्ट एन्कोडिंग ASCII है। अपने कोड पायथन 3 को संगत बनाना बहुत आसान है और इसके लिए इस नॉटी हैक की आवश्यकता नहीं होती है। उदाहरण के लिए यह बहुत ही वास्तविक समस्याएँ क्यों पैदा करता है, इस धारणा के साथ अमेज़ॅन के साथ मेरा अनुभव देखें: stackoverflow.com/questions/39465220/…
PYTHONIOENCODING="UTF-8"
मेरे Python2.7 Django-1.11 पर्यावरण की मदद की। धन्यवाद।
detect_encoding
।
detect_encoding
एक ऐसी विधि है जो भाषा के सुराग के आधार पर एक स्ट्रिंग के एन्कोडिंग का पता लगा सकती है।
#!/usr/bin/env python
#-*- coding: utf-8 -*-
u = u'moçambique'
print u.encode("utf-8")
print u
chmod +x test.py
./test.py
moçambique
moçambique
./test.py > output.txt
Traceback (most recent call last):
File "./test.py", line 5, in <module>
print u
UnicodeEncodeError: 'ascii' codec can't encode character
u'\xe7' in position 2: ordinal not in range(128)
शेल काम करता है, sdtout को नहीं भेज रहा है, ताकि एक वर्कअराउंड हो, stdout को लिखने के लिए।
मैंने अन्य दृष्टिकोण बनाया, जो sys.stdout.encoding परिभाषित नहीं होने पर या अन्य शब्दों में, चलाया नहीं जाता है, तो निर्यात करने के लिए लिखने के लिए पहले PYTHONIOENCODING = UTF-8 को निर्यात की आवश्यकता है।
import sys
if (sys.stdout.encoding is None):
print >> sys.stderr, "please set python env PYTHONIOENCODING=UTF-8, example: export PYTHONIOENCODING=UTF-8, when write to stdout."
exit(1)
इसलिए, एक ही उदाहरण का उपयोग कर:
export PYTHONIOENCODING=UTF-8
./test.py > output.txt
काम करेगा
पहला खतरा भीतर है reload(sys)
।
जब आप किसी मॉड्यूल को पुनः लोड करते हैं, तो आप वास्तव में अपने रनटाइम में मॉड्यूल की दो प्रतियां प्राप्त करते हैं। पुराना मॉड्यूल सब कुछ की तरह एक पायथन ऑब्जेक्ट है, और जब तक इसके संदर्भ हैं तब तक जीवित रहता है। तो, आधी वस्तुएं पुराने मॉड्यूल की ओर इशारा करती हैं, और आधी नई की ओर। जब आप कुछ बदलाव करते हैं, तो आप इसे कभी नहीं देखेंगे जब कोई यादृच्छिक वस्तु परिवर्तन नहीं देखती है:
(This is IPython shell)
In [1]: import sys
In [2]: sys.stdout
Out[2]: <colorama.ansitowin32.StreamWrapper at 0x3a2aac8>
In [3]: reload(sys)
<module 'sys' (built-in)>
In [4]: sys.stdout
Out[4]: <open file '<stdout>', mode 'w' at 0x00000000022E20C0>
In [11]: import IPython.terminal
In [14]: IPython.terminal.interactiveshell.sys.stdout
Out[14]: <colorama.ansitowin32.StreamWrapper at 0x3a9aac8>
अब, sys.setdefaultencoding()
उचित
यह सब प्रभावित करता है निहितार्थ रूपांतरण हैstr<->unicode
। अब, utf-8
ग्रह पर sanest एन्कोडिंग है (ASCII और सभी के साथ पीछे-संगत), अब रूपांतरण "बस काम करता है", क्या संभवतः गलत हो सकता है?
खैर, कुछ भी। और यही खतरा है।
UnicodeError
गैर-एएससीआईआई इनपुट के लिए फेंके जाने पर निर्भर करते हैं , या एक त्रुटि हैंडलर के साथ ट्रांसकोडिंग करते हैं, जो अब एक अप्रत्याशित परिणाम पैदा करता है। और चूंकि सभी कोड को डिफ़ॉल्ट सेटिंग के साथ परीक्षण किया जाता है, आप यहां "असमर्थित" क्षेत्र पर कड़ाई से हैं , और कोई भी आपको इस बारे में गारंटी नहीं देता है कि उनका कोड कैसे व्यवहार करेगा।