185

スクリプトの先頭でこれを使用する py スクリプトはほとんど見たことがありません。どのような場合に使用する必要がありますか?

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

4 に答える 4

155

ドキュメントによると:これにより、デフォルトのASCIIからUTF-8などの他のエンコーディングに切り替えることができます。これは、Pythonランタイムが文字列バッファをUnicodeにデコードする必要がある場合に常に使用します。

この関数は、Python が環境をスキャンするとき、Python の起動時にのみ使用できます。システム全体のモジュールで呼び出す必要があります, sitecustomize.py, このモジュールが評価された後、setdefaultencoding()関数はsysモジュールから削除されます.

実際に使用する唯一の方法は、属性を元に戻すリロード ハックを使用することです。

また、の使用sys.setdefaultencoding()は常に推奨されておらず、py3k ではノーオペレーションになっています。py3k のエンコーディングは「utf-8」に固定されており、それを変更するとエラーが発生します。

読むためのいくつかの指針を提案します:

于 2010-09-30T07:48:37.977 に答える
65

tl;dr

答えは決してありません!(自分が何をしているのか本当にわかっていない限り)

9/10 の解決策は、エンコード/デコードを正しく理解することで解決できます。

1/10 のユーザーはロケールまたは環境が正しく定義されておらず、以下を設定する必要があります。

PYTHONIOENCODING="UTF-8"  

コンソール印刷の問題を修正するために、環境で。

それは何をするためのものか?

sys.setdefaultencoding("utf-8")Python 2.x が Unicode() を str() (およびその逆) に変換する必要があり、エンコーディングが指定されていない場合に使用されるデフォルトのエンコーディング/デコーディングを変更します (再使用を避けるために取り消し線を引いてください)。すなわち:

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

Python 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)

sys.setdefaultencoding("utf-8")これらはには機能しますが、UTF-8 を使用しない人には必ずしも機能するとは限りません。ASCII のデフォルトにより、エンコーディングの仮定がコードに組み込まれないことが保証されます。

コンソール

sys.setdefaultencoding("utf-8")sys.stdout.encodingまた、コンソールに文字を出力するときに使用されるを修正するように見えるという副作用もあります。Python は、ユーザーのロケール (Linux/OS X/Un*x) またはコードページ (Windows) を使用してこれを設定します。場合によっては、ユーザーのロケールが壊れていて、コンソールのエンコーディング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.setdefaultencoding("utf-8")の何がそんなに悪いのですか?

デフォルトのエンコーディングが ASCII であることを理解した上で、人々は 16 年間 Python 2.x に対して開発を行ってきました。UnicodeError非 ASCII を含むことが判明した文字列の文字列から Unicode への変換を処理する例外処理メソッドが作成されました。

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"))

defaultencoding を設定する前は、このコードは ascii エンコーディングの「Å」をデコードできず、エンコーディングを推測して適切に Unicode に変換する例外ハンドラに入ります。印刷: オングストローム (Å®) がビジネスを運営します。defaultencoding を utf-8 に設定すると、コードは byte_string が utf-8 として解釈できることを検出し、データをマングルして代わりにこれを返します。

定数であるべきものを変更すると、依存するモジュールに劇的な影響があります。コードに出入りするデータを修正するだけのほうがよいでしょう。

問題例

次の例では、defaultencoding を UTF-8 に設定することは根本的な原因ではありませんが、問題がどのように隠蔽され、入力エンコーディングが変更されたときにコードがわかりにくい方法で破損するかを示しています 。 ' 位置 3131 のバイト 0x80 をデコードしない: 無効な開始バイト

于 2015-12-20T07:49:25.150 に答える
19
#!/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に書き込むための1つの回避策です。

sys.stdout.encodingが定義されていない場合、つまり、stdoutに書き込むには、最初にエクスポート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

動作します

于 2011-07-19T03:40:25.537 に答える