ベストアンサー
申し訳ありませんが、この問題に対する簡単な1行の回答はありません。
文字列がI / O操作(端末、ファイル、またはネットワークからの読み取り)を介してPythonプログラムに入力され、プログラムが場所から場所へコピーされることを想像してみてください。そして最後に、I / O操作を介して出力を取得します。途中のどの段階でも、ユニコードをstrに割り当てると、恐ろしいascii codec can"t encode...
エラーが表示されます。残念ながら、修正する以外に簡単な方法はありません。コードを介してすべてのスポットを修正します。
たとえば、次のことを考慮してください。
f\_in = open("filein.txt")
line = f\_in.read()
out\_msg = "The input line was: {line}".format(line=line)
f\_out = open("fileout.txt")
filein.txtを保存するときに使用されたエンコーディングがわからない限り、奇妙な動作が発生し、line
の一部の文字がゴミのように見えます(注:勝ちました) ascii codec can"t encode...
エラーが発生しますが、それでも結果は悪くなります。)したがって、 f\_in = codecs.open("filein.txt", "rb", "utf-8")
のようなものを使用して、必死に願う必要があります。 filein.txtを保存した人は誰でも、他のUTFエンコーディングではなくutf-8に保存していました。 (注:utf-8はasciiと上位互換性があるため、通常のasciiを使用して保存されたファイルは、utf-8エンコーディングを使用して正常に開きます。)
これまでに、明らかに、適切なUnicodeエンコーディングを使用してfileout.txtを開くと、再び問題が発生し、ascii codec can"t encode...
エラーが発生します(out\_msgにUnicode文字が含まれている場合)。したがって、codecs.open("fileout.txt", "wb", "utf-8")
。(注:utf-8エンコーディングを使用して通常のASCIIを格納することは、上位互換性があるため問題ありません。したがって、テキストにASCII以外のUnicode文字が含まれていない場合、utf-8でエンコードされたファイルは通常のASCIIファイルと同じです。)
私をつまずかせたのは、これら2つのことを行うだけでは不十分であるということでした。この更新されたコードを検討してください:
f\_in = codecs.open("filein.txt", "rb", "utf-8")
line = f\_in.read()
out\_msg = "The input line was: {line}".format(line=line)
f\_out = codecs.open("fileout.txt", "wb", "utf-8")
これでも、3番目に同じ恐ろしいエラーが発生する可能性がありますライン。そうです、問題は"The input line was: {line}".format(xxx)"
がstr
であり、line
にユニコード文字(ASCIIにエンコードできない文字を意味します)で問題が発生しました。
修正方法は次のとおりです。
out\_msg = u"The input line was: {line}".format(line=line)
(はい、この行はコードサンプルの3行目とは異なります。注意深く見る必要があります。)
これで完了です。通過する必要があります。コードのすべての行で、Unicodeがstrに割り当てられている(またはstrを予期するメソッドに送信されている)場所を見つけ、宛先をstrではなくunicodeに修正します。
Unicodeを理解するにはpythonの方が良いので、以下を見てください:http://farmdev.com/thoughts/23/what-i-thought-i-knew-about-unicode-in-python-amounted-to-nothing/
一般的なUnicodeを理解するには(そして私は非常にこれを行うことをお勧めします)Joel Spolskyの「すべてのソフトウェア開発者の絶対最小値絶対に、積極的にUnicodeと文字セットについて知っておく必要があります(いいえ言い訳!) “:http://www.joelonsoftware.com/articles/Unicode.html
そして、あなたがそれについて話している間、あなたは読むのもよいでしょう:ユニコードのベストプラクティスについて学ぶための最良の情報源は何ですかPythonで?
クイック “nダーティハック:出力を近似ASCIIで出力したいだけの場合は、次のことができます:
import unicodedata
line = unicodedata.normalize("NFKD", line).encode("ascii","ignore")
これにより、すべての非ASCII文字が最も近いASCII文字に置き換えられるか、適切でない場合は文字が無視されます。 。多くの目的に十分です…
回答
適切なエンコーディングを使用して、Unicode文字列(文字で構成され、メモリサイズから分離された単位)をバイトに変換する必要がありますI / Oを実行する前に。
デフォルトでは、Pythonはstdoutへの書き込み時にASCIIエンコードを使用して(つまり、を使用してUnicode文字列をエンコードしようとします。 print )ですが、このエンコーディングはすべてのUnicode文字を表すことができないため、「ascii」コーデックは「文字をエンコードできません」というエラーが発生します。かなり明示的です。
適切なエンコーディングを選択し、それを使用してUnicode文字列をエンコードする必要があります。たとえば、UTF-8は、すべてのUnicode文字を処理できる効率的なエンコーディングです。 foo がUnicode文字列であるとすると、次のように実行できます(実行する必要があります)。 print foo.encode( “utf -8 “) print foo の代わりに。ターミナルまたは選択したエンコーディングを理解しているものを確認してください。繰り返しになりますが、UTF-8は、このようなシナリオで最もホットなエンコーディングです。非常に具体的なニーズがない限り、UTF-8を使用することをお勧めします。