tl; dr /クイックフィックス
Python 2.xのUnicode Zen-ロングバージョン
ソースを確認しないと、根本的な原因を知るのは難しいので、一般的に説明する必要があります。
UnicodeDecodeError: 'ascii' codec can't decode byte一般strに、元の文字列のエンコーディングを指定せずに、非ASCIIを含むPython 2.x をUnicode文字列に変換しようとすると発生します。
簡単に言うと、Unicode文字列はエンコーディングをまったく含まない完全に別のタイプのPython文字列です。それらはUnicode ポイントコードのみを保持するため、スペクトル全体のあらゆるUnicodeポイントを保持できます。文字列には、UTF-8、UTF-16、ISO-8895-1、GBK、Big5などのエンコードされたテキストが含まれます。文字列はUnicodeにデコードされ、Unicodeは文字列にエンコードされます。ファイルとテキストデータは常にエンコードされた文字列で転送されます。
Markdownモジュールの作成者はおそらく、unicode()(例外がスローされる場合)コードの残りの部分に対する品質ゲートとして使用します。ASCIIを変換するか、既存のUnicode文字列を新しいUnicode文字列に再ラップします。Markdownの作成者は受信文字列のエンコードを認識できないため、Markdownに渡す前に文字列をUnicode文字列にデコードする必要があります。
Unicode文字列はu、文字列の接頭辞を使用してコードで宣言できます。例えば
>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>
Unicode文字列は、ファイル、データベース、ネットワークモジュールから取得される場合もあります。これが発生した場合、エンコーディングについて心配する必要はありません。
ガチャ
からstrUnicode への変換は、明示的にを呼び出さなくても発生する可能性がありますunicode()。
次のシナリオではUnicodeDecodeError例外が発生します。
# Explicit conversion without encoding
unicode('€')
# New style format string into Unicode string
# Python will try to convert value string to Unicode first
u"The currency is: {}".format('€')
# Old style format string into Unicode string
# Python will try to convert value string to Unicode first
u'The currency is: %s' % '€'
# Append string to Unicode
# Python will try to convert string to Unicode first
u'The currency is: ' + '€'
例
次の図でcaféは、端末のタイプに応じて、単語が「UTF-8」または「Cp1252」のいずれかのエンコーディングでエンコードされている様子を確認できます。どちらの例でも、cafは通常のASCIIです。UTF-8では、é2バイトを使用してエンコードされます。「Cp1252」では、éは0xE9です(これはたまたまUnicodeポイント値です(偶然ではありません))。正しいものdecode()が呼び出され、Python Unicodeへの変換が成功します。

この図でdecode()は、はとともに呼び出されますascii(これはunicode()エンコードを指定せずに呼び出すのと同じです)。ASCIIにはより大きいバイトを含めることができないため0x7F、これはUnicodeDecodeError例外をスローします。

Unicodeサンドイッチ
コード内にUnicodeサンドイッチを形成することをお勧めします。この場合、すべての受信データをUnicode文字列にデコードし、Unicodeを処理してからstr、途中でsにエンコードします。これにより、コードの途中で文字列のエンコードを心配する必要がなくなります。
入力/デコード
ソースコード
非ASCIIをソースコードに焼き付ける必要がある場合は、文字列の前にを付けてUnicode文字列を作成しますu。例えば
u'Zürich'
Pythonがソースコードをデコードできるようにするには、ファイルの実際のエンコーディングと一致するエンコーディングヘッダーを追加する必要があります。たとえば、ファイルが「UTF-8」としてエンコードされている場合は、次を使用します。
# encoding: utf-8
これは、ソースコードに非ASCIIが含まれている場合にのみ必要です。
ファイル
通常、非ASCIIデータはファイルから受信されます。ioモジュールは、指定されたを使用して、その場で自分のファイルをデコードがTextWrapperを提供しますencoding。ファイルには正しいエンコーディングを使用する必要があります-簡単に推測することはできません。たとえば、UTF-8ファイルの場合:
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
my_unicode_string = my_file.read()
my_unicode_stringその後、Markdownに渡すのに適しています。行UnicodeDecodeErrorからの場合は、read()おそらく間違ったエンコーディング値を使用しています。
CSVファイル
Python 2.7 CSVモジュールは非ASCII文字をサポートしていませんsupport。ただし、ヘルプはhttps://pypi.python.org/pypi/backports.csvで入手できます。
上記のように使用しますが、開いたファイルをそれに渡します。
from backports import csv
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
for row in csv.reader(my_file):
yield row
データベース
ほとんどのPythonデータベースドライバーはUnicodeでデータを返すことができますが、通常は少しの構成が必要です。SQLクエリには常にUnicode文字列を使用します。
MySQL
接続文字列に次を追加します。
charset='utf8',
use_unicode=True
例えば
>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
PostgreSQL
追加:
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)
HTTP
Webページは、ほぼすべてのエンコーディングでエンコードできます。Content-typeヘッダが含まれている必要がありcharsetエンコーディングでヒントにフィールドを。次に、コンテンツをこの値に対して手動でデコードできます。または、Python-RequestsはでUnicodeを返しますresponse.text。
手動で
文字列を手動でデコードする必要がある場合はmy_string.decode(encoding)、単にを実行できます。ここencodingで、は適切なエンコーディングです。Python 2.xでサポートされているコーデックは次のとおりです:標準エンコーディング。繰り返しにUnicodeDecodeErrorなりますが、取得すると、おそらく間違ったエンコーディングを取得しています。
サンドイッチのお肉
通常のstrsと同じようにUnicodeを操作します。
出力
stdout /印刷
printstdoutストリームを介して書き込みます。Pythonは、Unicodeがコンソールのエンコーディングにエンコードされるように、標準出力でエンコーダを構成しようとします。たとえば、Linuxシェルlocaleがのen_GB.UTF-8場合、出力はにエンコードされUTF-8ます。Windowsでは、8ビットのコードページに制限されます。
破損したロケールなど、コンソールの構成が正しくないと、予期しない印刷エラーが発生する可能性があります。PYTHONIOENCODING環境変数は、標準出力のエンコーディングを強制できます。
ファイル
入力と同じように、io.openUnicodeをエンコードされたバイト文字列に透過的に変換するために使用できます。
データベース
読み取りと同じ構成で、Unicodeを直接書き込むことができます。
Python 3
Python 3は、Python 2.xほどUnicodeに対応していませんが、このトピックの混乱はわずかです。たとえば、通常strはUnicode文字列になり、古いものstrは今bytesです。
デフォルトのエンコーディングはUTF-8であるため.decode()、エンコーディングを指定しないバイト文字列の場合、Python 3はUTF-8エンコーディングを使用します。これはおそらく人々のUnicode問題の50%を修正します。
さらに、open()デフォルトではテキストモードで動作するため、デコードされたstrもの(Unicodeのもの)を返します。エンコーディングはロケールから派生します。ロケールは、Un * xシステムではUTF-8、Windowsボックスでは8ビットコードページ(windows-1251など)になる傾向があります。
なぜ使用すべきではないのか sys.setdefaultencoding('utf8')
reload問題を隠すだけで、Python 3.xへの移行を妨げる厄介なハックです(使用する理由があります)。問題を理解し、根本的な原因を修正して、Unicode Zenを楽しんでください。pyスクリプトでsys.setdefaultencoding( "utf-8")を使用してはならない理由を参照してください。詳細については