2017-06-03 12 views
3

私もopen(file_name, encoding='utf-8')であれば、私は常にASCIIコーデックは、いくつかの文字を解読することはできませんというエラーを取得し、UTF-8でエンコードされたテキストファイルを読み込もうとするたびに(例えば。for line in f: print(line)を使用した場合)locale.getpreferredencoding()はなぜ 'UTF-8'ではなく 'ANSI_X3.4-1968'を返しますか?

Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import locale 
>>> locale.getpreferredencoding() 
'ANSI_X3.4-1968' 
>>> import sys 
>>> sys.getfilesystemencoding() 
'ascii' 
>>> 

localeコマンドをプリント:

locale: Cannot set LC_CTYPE to default locale: No such file or directory 
locale: Cannot set LC_ALL to default locale: No such file or directory 
LANG=en_US.UTF-8 
LANGUAGE= 
LC_CTYPE=en_HK.UTF-8 
LC_NUMERIC="en_US.UTF-8" 
LC_TIME="en_US.UTF-8" 
LC_COLLATE="en_US.UTF-8" 
LC_MONETARY="en_US.UTF-8" 
LC_MESSAGES="en_US.UTF-8" 
LC_PAPER="en_US.UTF-8" 
LC_NAME="en_US.UTF-8" 
LC_ADDRESS="en_US.UTF-8" 
LC_TELEPHONE="en_US.UTF-8" 
LC_MEASUREMENT="en_US.UTF-8" 
LC_IDENTIFICATION="en_US.UTF-8" 
LC_ALL= 

答えて

-2

エラーメッセージが間違っていると思います。区別するように注意してください。Unicode codeErrorUnicode En codeErrorです。

あなたは、「asciiコーデックではいくつかの文字をデコードできません」とPythonが苦情を言います。しかし、私が知る限り、そのようなエラーメッセージはありません。以下の2つのケースを比較します

>>> b = 'é'.encode('utf8') 
>>> b.decode('ascii') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can’t decode byte 0xc3 in position 0: ordinal not in range(128) 
>>> 'é'.encode('ascii') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can’t encode character '\xe9' in position 0: ordinal not in range(128) 

それはどちらかだ「バイトをデコードすることはできません」または「文字をエンコードすることができない」、それは「文字を解読することはできません」でしています。

これは知識をひけらかすように見えるかもしれないが、このラインでは、

for line in f: print(line) 

あなたは、両方のは(コロンの前)コーディングと EN(print式)をコーディング持っています。したがって、どのプロセスが問題を引き起こしているかを確認する必要があります。 1つの可能性は、これを2行で書くことです。

しかし、が開かれている場合は、encoding='utf-8'と書くと、printという表現で問題が発生していると確信しています。 print()はデフォルトでsys.stdoutに書き込みます。このストリームはPythonの起動時に既に開いているので、エンコーディングは環境に応じて既に設定されています。あなたのロケールではLC_ALLが設定されていないので、ASCIIのデフォルト値( "ANSI X3.4-1968")が使用されます(これはあなたの質問に答えます)。

:基礎となるバイナリストリームを使用

  • あなたができないか、ロケールを変更したくない場合は、ここであなたは、Python内からSTDOUTにUTF-8テキストを送信するために何ができるかです

    for line in f: 
        sys.stdout.buffer.write(line.encode('utf-8') 
    
  • 再エンコードsys.stdout(実際:再符号化されたバージョンとsys.stdoutを置き換える):

    いずれの場合においても

、それはあなたの端末が正常にUTF-8テキストを表示することができないということはまだ可能ですが、どちらかそうするように構成されていないので、それはそれのuncapableですかので。その場合、おそらく疑問符やモジバケが表示されます。しかし、それはPythonのコントロールの外に別の話です...

+0

@ jm33_m0あなたは私の答えをdownvoteましたか?それに何か悪いですか? – lenz

+0

私は 'LC_ALL'を設定していませんが、これらの関数からutf-8を取得しています... – skyking

+0

@skykingこれをテストすると、 'locale.getpreferredencoding()'の戻り値を 'LC_ALL'の設定/解除によって変更することができました。しかし、この関数のドキュメントは、それがプラットフォームに依存するヒューリスティックな推測であることを示しています。私は、物事が別の環境で異なって動作するのは驚くことではありません。要点は、使用するエンコーディングを制御する場合は、明示的に宣言します。 – lenz

関連する問題