আমরা পাই স্ক্রিপ্টে sys.setdeafultencoding ("utf-8") ব্যবহার করব না কেন?


165

আমি কয়েকটি পাই স্ক্রিপ্ট দেখেছি যা স্ক্রিপ্টের শীর্ষে এটি ব্যবহার করে। কোন ক্ষেত্রে এটি ব্যবহার করা উচিত?

import sys
reload(sys)
sys.setdefaultencoding("utf-8")

2
আইপিথনে এটি ব্যবহার করে একটি সমস্যা আছে,% সময় github.com/ipython/ipython/issues/8071
seanv507

3
@ সানভ 50০7, উত্তরগুলি পড়ুন - এটি ব্যবহার করে মারাত্মকভাবে নিরুৎসাহিত করা হয়েছে
অ্যালাস্টার ম্যাককর্ম্যাক


2
এটি কীভাবে sys.setdeafultencoding ('utf-8') এর বিপদগুলির সঠিক সদৃশ নয় ? যদিও এটি (2010) জিজ্ঞাসা করে এমনটি (2015)? তবে এই জিজ্ঞাসাটিরও ভাল উত্তর রয়েছে। কি করো? এছাড়াও, স্পষ্ট করে বলতে গেলে, এই প্রশ্নটি পাইথনকে 3 নয় 3 এ বোঝায়, তবুও এটি কোথাও ট্যাগ বা উল্লিখিত হয়নি।
smci

মূল্য পড়া ডাইভিং এর আগে তা উত্তর দিকে: pythonhosted.org/kitchen/unicode-frustrations.html
ccpizza

উত্তর:


141

ডকুমেন্টেশন অনুসারে: এটি আপনাকে ডিফল্ট ASCII থেকে অন্য এনকোডিংগুলিতে যেমন ইউটিএফ -8 এ স্যুইচ করতে দেয় যা পাইথন রানটাইমটি যখনই ইউনিকোডে স্ট্রিং বাফারটি ডিকোড করতে হয় তা ব্যবহার করবে।

পাইথন পরিবেশ স্ক্যান করলে এই ফাংশনটি কেবল পাইথন স্টার্ট-আপ সময়ে উপলভ্য। এটি একটি সিস্টেম-প্রশস্ত মডিউলে কল করতে হবে, sitecustomize.pyএই মডিউলটি মূল্যায়ন করার পরে, setdefaultencoding()ফাংশনটি sysমডিউল থেকে সরানো হবে ।

এটি ব্যবহারের একমাত্র উপায় হ'ল পুনরায় লোড হ্যাক যা বৈশিষ্ট্যটি ফিরিয়ে আনে।

এছাড়াও, এর ব্যবহারটি sys.setdefaultencoding()সর্বদা নিরুৎসাহিত করা হয়েছে , এবং এটি পাই 3 কে-তে কোনও বিকল্প নেই। পাই 3 কে এর এনকোডিংটি "ইউটিএফ -8" -তে শক্ত-ওয়্যার্ড এবং এটি পরিবর্তন করা একটি ত্রুটি উত্থাপন করে।

আমি পড়ার জন্য কিছু পয়েন্টার প্রস্তাব:


6
দুর্দান্ত জিনিস, যদিও এখানে অত্যধিক তথ্য দিয়ে কিছুটা মৃত্যুর কারণ রয়েছে। আমি এই নিবন্ধটিতে সর্বাধিক সর্বাধিক দৃষ্টি নিবদ্ধ রেখে শিখেছি: blog.notdot.net/2010/07/Getting-
ইউনিকোড-

3
আমি যুক্ত করতে চাই যে ডিফল্ট এনকোডিংটি এনকোডিংয়ের জন্যও ব্যবহৃত হয় ( এটিতে যখন এনকোডিং থাকে তখন লেখার sys.stdoutসময় Noneযেমন পাইথন প্রোগ্রামের আউটপুট পুনর্নির্দেশের সময়)।
এরিক হে লেবিগোট

14
"ব্যবহারের জন্য sys.setdefaultencoding()সর্বদা নিরুৎসাহিত করা হয়েছে " এর
জেএফএস

7
'হার্ড-ওয়্যার টু utf-8' সত্য নয়, এটি হার্ডওয়ার্ড নয় এবং এটি সর্বদা হয় না UTF-8LC_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(বা অন্য কিছু হতে পারে)
টিনো ২

7
@ টিনো, কনসোল এনকোডিং ডিফল্ট এনকোডিংয়ের থেকে পৃথক।
অ্যালিস্টার ম্যাককর্ম্যাক

58

TL; ড

উত্তরটি কখনও নেই ! (যদি না আপনি সত্যিই জানেন যে আপনি কী করছেন)

9-10 বার সমাধানটি এনকোডিং / ডিকোডিংয়ের সঠিক বোঝার সাথে সমাধান করা যেতে পারে।

1/10 জন লোকের একটি ভুলভাবে সংজ্ঞায়িত লোকেল বা পরিবেশ রয়েছে এবং সেট করতে হবে:

PYTHONIOENCODING="UTF-8"  

কনসোল মুদ্রণের সমস্যাগুলি ঠিক করতে তাদের পরিবেশে।

এটার কাজ কি?

sys.setdefaultencoding("utf-8")(পুনরায় ব্যবহার এড়ানোর জন্য আঘাত করা) যখনই পাইথন ২.x একটি ইউনিকোড () কে স্ট্র () এবং (তদ্বিপরীত) রূপান্তরিত করতে ব্যবহৃত হয় তখন ডিফল্ট এনকোডিং / ডিকোডিং পরিবর্তিত হয় এবং এনকোডিং দেওয়া হয় না। অর্থাৎ,

str(u"\u20AC")
unicode("€")
"{}".format(u"\u20AC") 

পাইথন ২.x-এ, ডিফল্ট এনকোডিংটি ASCII এ সেট করা থাকে এবং উপরের উদাহরণগুলি ব্যর্থ হবে:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)

(আমার কনসোলটি ইউটিএফ -8 হিসাবে কনফিগার করা হয়েছে "€" = '\xe2\x82\xac', সুতরাং ব্যতীত \xe2)

অথবা

UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 0: ordinal not in range(128)

sys.setdefaultencoding("utf-8")এগুলি আমার পক্ষে কাজ করার অনুমতি দেবে , তবে অগত্যা ইউটিএফ -8 ব্যবহার না করে এমন লোকদের জন্য কাজ করবে না। এএসসিআইআইয়ের ডিফল্টটি নিশ্চিত করে যে এনকোডিংয়ের অনুমানগুলি কোডে বেক করা হয়নি

কনসোল

sys.setdefaultencoding("utf-8")sys.stdout.encodingকনসোলে অক্ষর মুদ্রণ করার সময় ব্যবহার করা হয়, এটি ঠিক করতে উপস্থিত হওয়ার পার্শ্ব প্রতিক্রিয়াও রয়েছে । পাইথন এটি সেট করতে ব্যবহারকারীর লোকেল (লিনাক্স / ওএস এক্স / আন * এক্স) বা কোডপেজ (উইন্ডোজ) ব্যবহার করে। কখনও কখনও, কোনও ব্যবহারকারীর লোকেল ভাঙা হয় এবং কনসোল এনকোডিংটি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"
€

Sys.setdeafultencoding ("utf-8") এর সাথে এত খারাপ কী ?

ডিফল্ট এনকোডিংটি ASCII তা বোঝার জন্য লোকেরা 16 বছর ধরে পাইথন ২.x এর বিরুদ্ধে বিকাশ করছে। UnicodeErrorব্যতিক্রম হ্যান্ডলিং পদ্ধতিগুলি স্ট্রিংগুলিতে ইউনিকোড রূপান্তরগুলিতে নন-এএসসিআইআই রয়েছে বলে স্ট্রিং পরিচালনা করতে লেখা হয়েছিল।

Https://anonbadger.wordpress.com/2015/06/16/why-sys-setdeafultencoding-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"))

ডিফল্টকেনডিং সেট করার আগে এই কোডটি এস্কি এনকোডিংটিতে "Å" ডিকোড করতে অক্ষম হবে এবং তারপরে এনকোডিংটি অনুমান করতে এবং এটি সঠিকভাবে ইউনিকোডে রূপান্তর করতে ব্যতিক্রম হ্যান্ডলারটি প্রবেশ করবে। মুদ্রণ: অ্যাংস্ট্রোম (Å®) আপনার ব্যবসা চালায়। একবার আপনি ডিএফএল্টেনকোডিংটি utf-8 এ সেট করার পরে কোডটি খুঁজে পাবে যে বাইট_স্ট্রিংকে utf-8 হিসাবে ব্যাখ্যা করা যায় এবং সুতরাং এটি ডেটা মঙ্গল করে পরিবর্তে এটিকে ফিরিয়ে দেবে: অ্যাংস্ট্রোম (Ů) আপনার ব্যবসা চালায়।

ধ্রুবকটি কী হওয়া উচিত তা পরিবর্তনের ফলে আপনি যে মডিউলগুলির উপর নির্ভর করছেন তার উপর নাটকীয় প্রভাব পড়বে। আপনার কোডের ভিতরে এবং বাইরে আসা ডেটা ঠিক করা ভাল।

উদাহরণ সমস্যা

ইউটিএফ -8-তে ডিফল্টকোডিংয়ের সেটটি নিম্নলিখিত উদাহরণের মূল কারণ নয়, এটি কীভাবে সমস্যাগুলি মুখোশযুক্ত এবং কীভাবে ইনপুট এনকোডিং পরিবর্তন করার সময় কোডটি একটি অবিস্মরণীয়ভাবে ভেঙে দেয় তা দেখায়: ইউনিকোড ডিকোডেরর: 'utf8' কোডেক পারে 3131 পজিশনে 0x80 বাইট ডিকোড করবেন না: অবৈধ শুরু বাইট


2
এতে চমক sys.setdefaultencoding("utf-8")থাকলেও কোডটি পাইথন ৩ এর মতো আচরণ করা ভাল। এটি এখন 2017। এমনকি আপনি যখন 2015 সালে উত্তরটি লিখেছিলেন, তখনও আমি মনে করি পশ্চাদপটের পরিবর্তে সামনের দিকে তাকানো ইতিমধ্যে ভাল ছিল। এটি আসলে আমার জন্য সহজ সমাধান ছিল, যখন আমি পাই যে পাইপথন 2 এ আমার কোডটি আলাদাভাবে আচরণ করে আউটপুট পুনঃনির্দেশিত হয়েছে কিনা তার উপর নির্ভর করে (পাইথন 2 এর জন্য খুব বাজে সমস্যা)। বলা বাহুল্য, আমি ইতিমধ্যে # coding: utf-8পেয়েছি এবং পাইথন 3 এর জন্য আমার কোনও কার্যক্রমের প্রয়োজন নেই (আমাকে আসলে setdefaultencodingসংস্করণ চেকটি ব্যবহার করে মুখোশ করতে হবে )।
ইয়ংওয়ে উ উ

এটি দুর্দান্ত এবং এটি আপনার জন্য কাজ করে তবে sys.setdefaultencoding("utf-8")পাইথন ৩ এর সাথে আপনার পাই ২.x কোডটিকে সামঞ্জস্যপূর্ণ করে না Nor আপনার কোড পাইথন 3 সামঞ্জস্যপূর্ণ করা খুব সহজ এবং এই বাজে হ্যাকের প্রয়োজন হয় না। উদাহরণস্বরূপ, কেন এটি খুব বাস্তব সমস্যার সৃষ্টি করে, অ্যামাজন সম্পর্কে আমার এই ধারণাটি নিয়ে গণ্ডগোল দেখুন
অ্যালাস্টার ম্যাককর্ম্যাক

1
@ অ্যালাস্টারএমসি কর্কম্যাক আপনি রক করেছেন, আমার সাইটটি কয়েক মাস ধরে রয়েছে এবং কী করতে হবে তা বুঝতে পারেনি। অবশেষে, PYTHONIOENCODING="UTF-8"আমার পাইথন 2.7 জাজানো -১.১১ পরিবেশকে সহায়তা করেছে। ধন্যবাদ।
সোম

আমি জানি আপনি উদাহরণটি অনুলিপি করেছেন তবে প্যাকেজটি কী আছে তা আমি খুঁজে পেতে পারি detect_encoding
dlamblin

@ ডালামব্লিন কোড উদাহরণটি উদ্ধৃতি প্রমাণ করার জন্য এবং আপনার কোডে ব্যবহার করার কথা নয়। ভাবুন যে এটি detect_encodingএমন একটি পদ্ধতি যা ভাষার ক্লুগুলির উপর ভিত্তি করে কোনও স্ট্রিংয়ের এনকোডিং সনাক্ত করতে পারে।
অ্যালাস্টার ম্যাককর্ম্যাক

18
#!/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 সংজ্ঞায়িত না করা থাকলে বা অন্য কথায় স্টেডআউটে লেখার জন্য প্রথমে পাইথনিওইনকোডিং = ইউটিএফ -8 রফতানি দরকার need

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

কাজ করবে


3
এটি জিজ্ঞাসিত প্রশ্নের উত্তর দেয় না। বরং বিষয় সম্পর্কে কিছু স্পর্শকাতর চিন্তাভাবনা।
ivan_pozdeev

3
  • প্রথম বিপদটি নিহিত 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গ্রহে স্যানেস্ট এনকোডিং (এএসসিআইআই এবং সকলের সাথে পিছিয়ে-সুসংগত), রূপান্তর এখন "কেবলমাত্র কাজ করে", সম্ভবত কী ভুল হতে পারে?

    ভাল, কিছু। আর এটাই বিপদ।

    • কিছু কোড থাকতে পারে যা UnicodeErrorনন-এসসিআইআই ইনপুটটির জন্য নিক্ষিপ্ত হওয়ার উপর নির্ভর করে , বা ত্রুটি হ্যান্ডলারের সাথে ট্রান্সকোডিং করছে, যা এখন একটি অপ্রত্যাশিত ফলাফল তৈরি করে। এবং যেহেতু সমস্ত কোডটি ডিফল্ট সেটিংসের মাধ্যমে পরীক্ষা করা হয়, আপনি এখানে কঠোরভাবে "অসমর্থিত" অঞ্চলটিতে রয়েছেন এবং তাদের কোড কী আচরণ করবে সে সম্পর্কে কেউ আপনাকে গ্যারান্টি দেয় না।
    • ট্রান্সকোডিং অপ্রত্যাশিত বা অব্যবহৃত ফলাফল আনতে পারে যদি সিস্টেমের সমস্ত কিছু ইউটিএফ -8 ব্যবহার না করে কারণ পাইথন 2 আসলে একাধিক স্বতন্ত্র "ডিফল্ট স্ট্রিং এনকোডিংস" রয়েছে । (মনে রাখবেন, একটি প্রোগ্রাম অবশ্যই গ্রাহকের জন্য গ্রাহকের সরঞ্জামে কাজ করবে।)
      • আবার সবচেয়ে খারাপ বিষয়টি হ'ল আপনি কখনই বুঝতে পারবেন না কারণ রূপান্তর অন্তর্নিহিত - কখন এবং কোথায় ঘটে তা আপনি সত্যই জানেন না। (পাইথন জেন, কোয়ান 2 অহয়!) আপনি কখনই বুঝতে পারবেন না যে আপনার কোড কেন একটি সিস্টেমে কাজ করে এবং অন্যটিতে ব্রেক করে। (বা আরও ভাল, আইডিইতে কাজ করে এবং কনসোলে বিরতি দেয়))
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.