पायथन के डिफ़ॉल्ट एन्कोडिंग को बदलना?


143

जब मैं कंसोल से अपने एप्लिकेशन चलाता हूं तो मेरे पास कई "एनकोडिंग" नहीं हो सकती है और पायथन के साथ समस्याओं को "डिकोड नहीं कर सकता है" । लेकिन ग्रहण PyDev IDE में, डिफ़ॉल्ट वर्ण एन्कोडिंग UTF-8 पर सेट है , और मैं ठीक हूं।

मैंने डिफ़ॉल्ट एन्कोडिंग सेट करने के लिए चारों ओर खोज की, और लोग कहते हैं कि पायथन sys.setdefaultencodingस्टार्टअप पर कार्य को हटा देता है, और हम इसका उपयोग नहीं कर सकते।

तो इसके लिए सबसे अच्छा उपाय क्या है?



3
The best solution is to learn to use encode and decode correctly instead of using hacks.यह निश्चित रूप से python2 के साथ हमेशा अपने स्वयं के इंटरफ़ेस का उपयोग करके ऐसा करने / लगातार याद रखने की कीमत पर संभव था । मेरा अनुभव बताता है कि यह अत्यधिक समस्याग्रस्त हो जाता है जब आप कोड लिख रहे होते हैं जिसे आप python2 और python3 दोनों के साथ काम करना चाहते हैं।
आरएच

जवाबों:


159

यहां एक सरल विधि (हैक) है जो आपको उस setdefaultencoding()फ़ंक्शन को वापस देती है जिसे यहां से हटा दिया गया था sys:

import sys
# sys.setdefaultencoding() does not exist, here!
reload(sys)  # Reload does the trick!
sys.setdefaultencoding('UTF8')

(3.4+ अजगर के लिए नोट: reload()में है importlibपुस्तकालय।)

हालांकि, यह एक सुरक्षित बात नहीं है , हालांकि: यह स्पष्ट रूप से एक हैक है, क्योंकि अजगर के शुरू होने के बाद sys.setdefaultencoding()से जानबूझकर हटा दिया sysजाता है। इसे फिर से सक्रिय करना और डिफ़ॉल्ट एन्कोडिंग को बदलना कोड को तोड़ सकता है जो एएससीआईआई पर निर्भर करता है जो डिफ़ॉल्ट है (यह कोड तृतीय-पक्ष हो सकता है, जो आमतौर पर इसे असंभव या खतरनाक बनाना तय करता है)।


5
मैंने अस्वीकार कर दिया, क्योंकि यह उत्तर मौजूदा अनुप्रयोगों को चलाने के लिए मदद नहीं करता है (जो कि प्रश्न की व्याख्या करने का एक तरीका है), गलत है जब आप एक पुस्तकालय लिख रहे हैं / आवेदन और खतरनाक बना रहे हैं। सही तरीका सेट करना है LC_CTYPE(या किसी एप्लिकेशन में, जांचें कि क्या यह सही सेट है और सार्थक त्रुटि संदेश के साथ गर्भपात करता है)।
ibotty

@ibotty मैं सहमत हूं कि यह उत्तर हैक है और इसका उपयोग करना खतरनाक है। यह प्रश्न का उत्तर देता है, हालांकि ("पायथन के डिफ़ॉल्ट एन्कोडिंग को बदलना")। क्या आपके पास पायथन दुभाषिया पर पर्यावरण चर LC_CTYPE के प्रभाव के बारे में एक संदर्भ है?
एरिक ओ लेबिगोट

ठीक है, यह उल्लेख नहीं किया, यह पहली बार में एक हैक है। इसके अलावा, खतरनाक उत्तर जो किसी भी कमी का उल्लेख करते हैं कि वे मददगार नहीं हैं।
ibotty

1
@ आप सही हैं। यह हालांकि (अजगर 2 और 3 में) वरीयता पर प्रभाव LC_CTYPE=C python -c 'import locale; print( locale.getpreferredencoding())'
डालता है

1
@ user2394901 sys.setdefaultencoding () का उपयोग हमेशा हतोत्साहित किया गया है !! और py3k की एन्कोडिंग "utf-8" के लिए हार्ड-वायर्ड है और इसे बदलना एक त्रुटि उठाता है।
मार्लोन एबेकून

70

यदि आपको अपनी स्क्रिप्ट के आउटपुट को पुनर्निर्देशित करने का प्रयास करते समय यह त्रुटि मिलती है

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)

बस कंसोल में PYTHONIOENCODING निर्यात करें और फिर अपना कोड चलाएं।

export PYTHONIOENCODING=utf8


3
यह एकमात्र समाधान है जिसने मेरे लिए कोई अंतर नहीं रखा। - मैं डेबियन 7 पर हूं, टूटी हुई लोकेल सेटिंग के साथ। धन्यवाद।
प्रीयो

4
LC_CTYPEबदले में कुछ समझदार करने के लिए सेट करें । यह अन्य सभी कार्यक्रमों को भी खुश करता है।
आइबोटी

5
Python3 में एक बड़ा बग है, वह PYTHONIOENCODING=utf8डिफ़ॉल्ट नहीं है। इससे स्क्रिप्ट सिर्फ इसलिए टूट जाती हैLC_ALL=C
टीनो

Set LC_CTYPE to something sensible insteadयह एक उचित सुझाव है। यह इतनी अच्छी तरह से काम नहीं करता है जब आप कोड को वितरित करने की कोशिश कर रहे हैं जो सिर्फ दूसरे व्यक्ति के सिस्टम पर काम करता है।
आरएच

डेबियन और रेडहाट ओएस C.utf8अधिक समझदार सी प्रदान करने के लिए एक लोकेल का उपयोग करते हैं। ग्लिब्क अपस्ट्रीम इसे जोड़ने पर काम कर रहा है, इसलिए शायद हमें लोकेल सेटिंग का सम्मान करने के लिए पायथन को दोष नहीं देना चाहिए?
आर्थर

52

ए) sys.getdefaultencoding()उत्पादन को नियंत्रित करने के लिए :

python -c 'import sys; print(sys.getdefaultencoding())'

ascii

फिर

echo "import sys; sys.setdefaultencoding('utf-16-be')" > sitecustomize.py

तथा

PYTHONPATH=".:$PYTHONPATH" python -c 'import sys; print(sys.getdefaultencoding())'

utf-16-be

आप अपने sitecustomize.py को अपने में उच्चतर रख सकते हैं PYTHONPATH

इसके अलावा आप reload(sys).setdefaultencoding@EOL द्वारा प्रयास करना पसंद कर सकते हैं

बी) नियंत्रण के लिए stdin.encodingऔर stdout.encodingआप सेट करना चाहते हैं PYTHONIOENCODING:

python -c 'import sys; print(sys.stdin.encoding, sys.stdout.encoding)'

ascii ascii

फिर

PYTHONIOENCODING="utf-16-be" python -c 'import sys; 
print(sys.stdin.encoding, sys.stdout.encoding)'

utf-16-be utf-16-be

अंत में: आप ए) या बी) या दोनों का उपयोग कर सकते हैं !


(केवल from __future__ import unicode_literals
python2

17

PyDev 3.4.1 से शुरू होकर , डिफ़ॉल्ट एन्कोडिंग को अब बदला नहीं जा रहा है। देखें इस टिकट जानकारी के लिए।

पुराने संस्करणों के लिए एक समाधान यह सुनिश्चित करने के लिए है कि PyDev डिफ़ॉल्ट एन्कोडिंग के रूप में UTF-8 के साथ नहीं चलता है। ग्रहण के तहत, संवाद सेटिंग्स ("रन कॉन्फ़िगरेशन", अगर मुझे सही याद है); आप सामान्य टैब पर डिफ़ॉल्ट एन्कोडिंग चुन सकते हैं। यदि आप इन त्रुटियों को 'जल्दी' (दूसरे शब्दों में: अपने PyDev वातावरण में) करना चाहते हैं, तो इसे US-ASCII में बदलें। इस वर्कअराउंड के लिए एक मूल ब्लॉग पोस्ट भी देखें ।


1
धन्यवाद क्रिस। विशेष रूप से ऊपर मार्क टी की टिप्पणी पर विचार करते हुए, आपका उत्तर मुझे सबसे उपयुक्त लगता है। और किसी के लिए जो मुख्य रूप से एक ग्रहण / PyDev उपयोगकर्ता नहीं है, मुझे कभी भी यह पता नहीं चला होगा कि मैं अपने दम पर बाहर आया हूँ।
सीन

मैं इसे विश्व स्तर पर बदलना चाहता हूं (रन कॉन्फ़िगरेशन के अनुसार एक बार), लेकिन यह पता नहीं चला है कि कैसे - एक अलग q पूछा है: stackoverflow.com/questions/9394277/…
टिम डिगिन्स

13

Python2 (और python2 केवल) के बारे में, कुछ पूर्व उत्तर निम्नलिखित हैक का उपयोग करने पर भरोसा करते हैं:

import sys
reload(sys)  # Reload is a hack
sys.setdefaultencoding('UTF8')

इसका उपयोग करने के लिए इसे हतोत्साहित किया जाता है ( इस या इसे देखें )

मेरे मामले में, यह एक साइड-इफेक्ट के साथ आता है: मैं ipython पुस्तिकाओं का उपयोग कर रहा हूं, और एक बार जब मैं कोड चलाता हूं longerprint works फ़ंक्शन अब काम नहीं करता है। मुझे लगता है कि इसका समाधान होगा, लेकिन फिर भी मुझे लगता है कि हैक का उपयोग करना सही विकल्प नहीं होना चाहिए।

कई विकल्पों की कोशिश करने के बाद, मेरे लिए काम करने वाला उसी कोडsitecustomize.py का उपयोग कर रहा था , जहां कोड का टुकड़ा होना है । उस मॉड्यूल का मूल्यांकन करने के बाद, सेटडेफॉल्टेनकोडिंग फ़ंक्शन को सिस से हटा दिया जाता है।

तो /usr/lib/python2.7/sitecustomize.pyकोड दर्ज करने के लिए समाधान को संलग्न करना है :

import sys
sys.setdefaultencoding('UTF8')

जब मैं virtualenvwrapper फ़ाइल का उपयोग करता हूं तो मैं संपादित करता हूं ~/.virtualenvs/venv-name/lib/python2.7/sitecustomize.py

और जब मैं अजगर नोटबुक्स और कोंडा के साथ उपयोग करता हूं, तो यह है ~/anaconda2/lib/python2.7/sitecustomize.py


8

इसके बारे में एक असंवेदनशील ब्लॉग पोस्ट है।

Https://anonbadger.wordpress.com/2015/06/16/why-sys-setdefaultencoding-will-break-code/ देखें ।

मैं इसकी सामग्री को नीचा दिखाता हूँ।

अजगर 2 में, जो स्ट्रिंग्स के एन्कोडिंग के बारे में दृढ़ता से टाइप नहीं किया गया था, आप अलग-अलग एन्कोड किए गए स्ट्रिंग्स पर ऑपरेशन कर सकते हैं, और सफल हो सकते हैं। उदा। निम्नलिखित वापस आ जाएगा True

u'Toshio' == 'Toshio'

यह हर (सामान्य, उपसर्ग) स्ट्रिंग के लिए धारण करेगा जो कि इनकोडेड था sys.getdefaultencoding(), जो कि डिफ़ॉल्ट था ascii, लेकिन अन्य नहीं।

डिफ़ॉल्ट एन्कोडिंग को सिस्टम-वाइड में परिवर्तित किया जाना था site.py, लेकिन कहीं और नहीं। उपयोगकर्ता मॉड्यूल में इसे सेट करने के लिए हैक्स (यहां भी प्रस्तुत किया गया) बस थे: हैक्स, समाधान नहीं।

पायथन 3 ने सिस्टम एन्कोडिंग को डिफ़ॉल्ट रूप से utf-8 में बदल दिया (जब LC_CTYPE यूनिकोड-अवगत है), लेकिन जब भी यूनिकोड स्ट्रिंग्स का उपयोग किया जाता है, तो "बाइट" स्ट्रिंग्स को स्पष्ट रूप से एनकोड करने की आवश्यकता के साथ मूलभूत समस्या को हल किया गया था।


4

पहला: reload(sys)आउटपुट टर्मिनल स्ट्रीम की आवश्यकता के संबंध में कुछ यादृच्छिक डिफ़ॉल्ट एन्कोडिंग सेट करना बुरा व्यवहार है। reloadअक्सर sys में चीजें बदलती हैं जो पर्यावरण के आधार पर रखी गई हैं - जैसे sys.stdin / stdout स्ट्रीम, sys.excepthook, आदि।

Stout पर सांकेतिक शब्दों में बदलना समस्या का समाधान

Sys.stdout पर print'यूनिकोड स्ट्रिंग्स और परे- strएससीआई (जैसे शाब्दिक से) के एन्कोडिंग समस्या को हल करने के लिए मुझे पता है कि सबसे अच्छा समाधान है: एक sys.stdout (फ़ाइल जैसी वस्तु) का ध्यान रखना जो सक्षम है और वैकल्पिक रूप से जरूरतों के बारे में सहिष्णु:

  • जब sys.stdout.encodingहै Noneकिसी कारण से, या गैर मौजूदा, या ग़लती से झूठी या "कम" क्या stdout टर्मिनल या वास्तव में धारा में सक्षम है की तुलना में है, तो एक सही प्रदान करने की कोशिश .encodingविशेषता। sys.stdout & sys.stderrएक ट्रांसलेटिंग फ़ाइल जैसी ऑब्जेक्ट द्वारा प्रतिस्थापित करके।

  • जब टर्मिनल / स्ट्रीम अभी भी सभी यूनिकोड वर्णों को एन्कोड नहीं कर सकता है, और जब आप printकेवल उसी के कारण ब्रेक नहीं करना चाहते हैं , तो आप ट्रांसलेटिंग फ़ाइल की तरह ऑब्जेक्ट में एक एन्कोड-विद-बिहेव व्यवहार प्रस्तुत कर सकते हैं।

यहाँ एक उदाहरण है:

#!/usr/bin/env python
# encoding: utf-8
import sys

class SmartStdout:
    def __init__(self, encoding=None, org_stdout=None):
        if org_stdout is None:
            org_stdout = getattr(sys.stdout, 'org_stdout', sys.stdout)
        self.org_stdout = org_stdout
        self.encoding = encoding or \
                        getattr(org_stdout, 'encoding', None) or 'utf-8'
    def write(self, s):
        self.org_stdout.write(s.encode(self.encoding, 'backslashreplace'))
    def __getattr__(self, name):
        return getattr(self.org_stdout, name)

if __name__ == '__main__':
    if sys.stdout.isatty():
        sys.stdout = sys.stderr = SmartStdout()

    us = u'aouäöüфżß²'
    print us
    sys.stdout.flush()

पायथन 2/2 + 3 कोड में परे-एससीआई सादे स्ट्रिंग शाब्दिक का उपयोग करना

वैश्विक डिफ़ॉल्ट एन्कोडिंग (केवल UTF-8 में बदलने का एकमात्र कारण) मुझे लगता है कि एक एप्लिकेशन स्रोत कोड निर्णय के बारे में है - और I / O स्ट्रीम एन्कोडिंग मुद्दों के कारण नहीं: कोड से परे-एएससीआई स्ट्रिंग शाब्दिक को मजबूर किए बिना लिखने के लिए। हमेशा u'string'स्टाइल यूनिकोड से बचने के लिए। यह लगातार किया जा सकता है ( पायोन 2 या पायथन 2 + 3 स्रोत कोड के आधार पर जो असिसी या यूटीएफ -8 सादे स्ट्रिंग शाब्दिक का लगातार उपयोग करता है - जहां तक ​​ये तार संभावित रूप से चुप रहते हैं यूनिकोड रूपांतरण और मॉड्यूल के बीच चलते हैं या संभावित रूप से stdout में जाते हैं। उसके लिए, पसंद करें "# encoding: utf-8"या ascii (कोई घोषणा नहीं)। परिवर्तन या ड्रॉप लाइब्रेरी जो अभी भी chr # 127 (जो कि आज दुर्लभ है) से परे ascii डिफ़ॉल्ट एन्कोडिंग त्रुटियों पर बहुत विनम्रतापूर्वक निर्भर करती है।

और आवेदन शुरू होने पर (और / या sitecustomize.py के माध्यम से) SmartStdoutऊपर की योजना के अलावा - बिना उपयोग किए reload(sys):

...
def set_defaultencoding_globally(encoding='utf-8'):
    assert sys.getdefaultencoding() in ('ascii', 'mbcs', encoding)
    import imp
    _sys_org = imp.load_dynamic('_sys_org', 'sys')
    _sys_org.setdefaultencoding(encoding)

if __name__ == '__main__':
    sys.stdout = sys.stderr = SmartStdout()
    set_defaultencoding_globally('utf-8') 
    s = 'aouäöüфżß²'
    print s

इस तरह से स्ट्रिंग शाब्दिक और अधिकांश ऑपरेशन (चरित्र पुनरावृत्ति को छोड़कर) यूनिकोड रूपांतरण के बारे में सोचने के बिना आराम से काम करते हैं जैसे कि केवल पायथ्रो 3 होगा। फ़ाइल I / O को निश्चित रूप से एन्कोडिंग के संबंध में विशेष देखभाल की आवश्यकता है - जैसा कि पायथन 3 में है।

नोट: मैदानी स्ट्रिंग्स SmartStdoutको आउटपुट स्ट्रीम एन्कोडिंग में परिवर्तित होने से पहले यूनिकोड से यूनिकोड में परिवर्तित किया जाता है।


4

यहाँ दृष्टिकोण मैं उत्पादन कोड है कि दोनों के साथ संगत था के लिए इस्तेमाल किया है को Python2 और python3 और हमेशा उत्पादित UTF8 उत्पादन। मुझे यह उत्तर कहीं और मिला, लेकिन मुझे स्रोत याद नहीं है।

यह दृष्टिकोण sys.stdoutकुछ ऐसी फ़ाइल के साथ प्रतिस्थापित करके काम करता है जो काफी फ़ाइल-जैसा नहीं है (लेकिन अभी भी केवल मानक लाइब्रेरी में चीजों का उपयोग कर रहा है)। यह आपके अंतर्निहित पुस्तकालयों के लिए अच्छी तरह से समस्याएं पैदा कर सकता है, लेकिन सरल मामले में जहां आपके पास अच्छा नियंत्रण है कि आपके ढांचे के माध्यम से sys.stdout का उपयोग कैसे किया जाता है यह एक उचित दृष्टिकोण हो सकता है।

sys.stdout = io.open(sys.stdout.fileno(), 'w', encoding='utf8')

3

यह मेरे लिए मुद्दा तय किया।

import os
os.environ["PYTHONIOENCODING"] = "utf-8"

1

यह किसी के लिए भी एक त्वरित हैक है जो (1) एक विंडोज प्लेटफ़ॉर्म (2) पर पायथन 2.7 और (3) चल रहा है क्योंकि सॉफ्टवेयर का एक अच्छा टुकड़ा (यानी, आपके द्वारा लिखित नहीं है तो तुरंत एनकोड / डिकोड प्रिंटिंग के लिए उम्मीदवार नहीं है) युद्धाभ्यास) IDLE वातावरण में "सुंदर यूनिकोड वर्ण" को प्रदर्शित नहीं करेगा (Pythonwin प्रिंट्स यूनिकोड फाइन), उदाहरण के लिए, साफ प्रथम ऑर्डर लॉजिक सिंबल जो कि Stephan Boyer आउटपुट में अपने पेडगॉग प्रोवर से फर्स्ट ऑर्डर लॉजिक लॉजिक प्रोवर में उपयोग करता है ।

मुझे एक sys रीलोड के लिए बाध्य करने का विचार पसंद नहीं आया और मैं PYTHONIOENCODING (जैसे कि प्रत्यक्ष Windows पर्यावरण चर को आज़माया और साइट-पैकेजों में साइटकेक-पैकेज में एक के रूप में छोड़ने की कोशिश कर रहा है) जैसे पर्यावरण चर के साथ सहयोग करने के लिए सिस्टम प्राप्त नहीं कर सका। लाइनर = 'utf-8')।

इसलिए, यदि आप सफलता के लिए अपना रास्ता हैक करने को तैयार हैं, तो अपनी आईडीएलई निर्देशिका पर जाएं, आमतौर पर: "C: \ Python27 \ Lib \ idlelib" IOBinding.py फ़ाइल का पता लगाएँ। उस फ़ाइल की एक प्रतिलिपि बनाएँ और इसे कहीं और संग्रहीत करें ताकि आप चुनते समय मूल व्यवहार पर वापस लौट सकें। एक संपादक (जैसे, आईडीएलई) के साथ आइडलिब में फ़ाइल खोलें। इस कोड क्षेत्र पर जाएं:

# Encoding for file names
filesystemencoding = sys.getfilesystemencoding()

encoding = "ascii"
if sys.platform == 'win32':
    # On Windows, we could use "mbcs". However, to give the user
    # a portable encoding name, we need to find the code page 
    try:
        # --> 6/5/17 hack to force IDLE to display utf-8 rather than cp1252
        # --> encoding = locale.getdefaultlocale()[1]
        encoding = 'utf-8'
        codecs.lookup(encoding)
    except LookupError:
        pass

दूसरे शब्दों में, ' try ' के बाद मूल कोड लाइन पर टिप्पणी करें जो एन्कोडिंग वैरिएबल को locale.getdefaultlocale के बराबर बना रही थी (क्योंकि इससे आपको cp1252 मिलेगा जो आप नहीं चाहते हैं) और इसके बजाय इसे 'utf-8' के लिए बाध्य करें '(लाइन' एन्कोडिंग = 'utf-8 ' को जोड़कर दिखाया गया है)।

मेरा मानना ​​है कि यह केवल IDLE डिस्प्ले को स्टडआउट करने के लिए प्रभावित करता है, न कि फ़ाइल नामों आदि के लिए उपयोग किए जाने वाले एन्कोडिंग पर (जो कि फाइलसिस्टेनसिंग लीडिंग में प्राप्त होता है)। यदि आपको बाद में आईडीएलई में चलने वाले किसी अन्य कोड के साथ कोई समस्या है, तो बस IOBinding.py फ़ाइल को मूल अनमॉडिफाइड फ़ाइल से बदल दें।


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