web-dev-qa-db-ja.com

Python 3に切り替えてUnicodeDecodeErrorを引き起こす

SublimeにPython3インタープリターを追加したところ、次のコードが機能しなくなりました。

for directory in directoryList:
    fileList = os.listdir(directory)
    for filename in fileList:
        filename = os.path.join(directory, filename)
        currentFile = open(filename, 'rt')
        for line in currentFile:               ##Here comes the exception.
            currentLine = line.split(' ')
            for Word in currentLine:
                if Word.lower() not in bigBagOfWords:
                    bigBagOfWords.append(Word.lower())
        currentFile.close()

次の例外が発生します。

  File "/Users/Kuba/Desktop/DictionaryCreator.py", line 11, in <module>
    for line in currentFile:
  File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/encodings/ascii.py", line 26, in decode
    return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xcc in position 305: ordinal not in range(128)

私が知る限り、Python3はどこでもutf-8をサポートするはずだからです。さらに、Python2.7ではまったく同じコードが問題なく機能します。環境変数PYTHONIOENCODINGの追加について読みましたが、試してみました-役に立たない(ただし、OS X Mavericksで環境変数を追加するのはそれほど簡単ではないようですので、変数を追加しますか?/etc/launchd.confを変更しました)

23
3yakuya

Python 3decodes読み取り時のテキストファイル、encodes書き込み時。デフォルトのエンコーディングは locale.getpreferredencoding(False) から取得されます。これは明らかに、セットアップでは_'ASCII'_を返します。 open() function documenation を参照してください:

テキストモードで、encodingが指定されていない場合、使用されるエンコーディングはプラットフォームに依存します。現在のロケールエンコーディングを取得するためにlocale.getpreferredencoding(False)が呼び出されます。

システム設定に依存する代わりに、明示的なコーデックを使用してテキストファイルを開く必要があります。

_currentFile = open(filename, 'rt', encoding='latin1')
_

encodingパラメーターを設定して、読み取り中のファイルに一致させます。

Python 3は、ソースコードのデフォルトとしてUTF-8をサポートしています。

同じことが書き込み可能なテキストファイルへの書き込みにも当てはまります。書き込まれたデータはエンコードされます。システムのエンコードに依存している場合、適切なコーデックを明示的に設定しない限り、UnicodeEncodingError例外が発生する可能性があります。書き込み時にどのコーデックを使用するかは、どのテキストを書いているか、そしてその後ファイルをどうするかによって異なります。

Python 3とUnicode nicode HOWTO のUnicodeを参照してください。ソースコードのエンコードとUnicodeデータの読み取りと書き込みの両方について説明しています。

60
Martijn Pieters

「私の知る限り、Python3はどこでもutf-8をサポートするはずです...」 python 3.6があり、デフォルトのエンコーディングはutf-8ではありません。私のコードでutf-8に変更するには、以下を使用します。

import locale
def getpreferredencoding(do_setlocale = True):
   return "utf-8"
locale.getpreferredencoding = getpreferredencoding

「ロケール優先エンコーディング」の変更Python

0
farid khafizov