ここでの問題は.write
、ファイル オブジェクトのメソッドがナイーブに Unicode 文字列を変換しようとしていることです (Python 2.x を使用している場合、これはunicode
型になります)。それをバイト文字列 (Python を使用している場合) に渡します。 2.x、これはstr
ASCII コーデックを使用するタイプになりますが、渡す Unicode 文字列は ASCII を使用して表すことができません。これは、ASCII 文字セットの一部ではない (日本語の) 文字が含まれているためです。
保存する前に、Unicode 文字列のメソッドを使用して、.encode
その文字列を表す一連のバイトに変換する必要があります。これは基本的str
に、Python 2.x で型が表すものです。単なる一連のバイトであり、予想されるような一連の文字ではありません。print
ただし、Python は、 type の変数をstr
使用すると、システムのデフォルトの Unicode エンコーディングを使用して、端末に一連の文字として表示されるため、別の考え方を簡単にさせることができます。
ここで文字列をエンコードするためにどのエンコーディングを使用する必要があるかは、ユースケースによって異なります。UTF-8 が最も一般的であり、単純にそれを使用したい場合もありますが、書き込んでいるファイルが同じシステムのテキスト エディターで正しく表示されることを確認したい場合は、UTF-8 を備えたデバイスで実行した場合でも同様です。 UTF-16 のような一般的ではないシステム エンコーディングの代わりに、システムのデフォルト エンコーディングを使用することもできます (文字列をエンコードできないデフォルト エンコーディングがシステムにある場合は、もちろん失敗します)。
つまり、ほぼ確実に、次のいずれかを実行する必要があります。
a)
f.write(textwrap.dedent(the_string).encode('utf-8'))
b)
import sys
f.write(textwrap.dedent(the_string).encode(sys.getdefaultencoding()))
非 ASCII テキストをファイルに書き込むというかなり基本的なタスクを実行するために頭を悩ませるのは、かなり面倒で複雑な作業だと思われる場合は、同意します。初めてのプログラミング言語である Python を使い始めたとき、Unicode、文字列エンコーディング、それに関連する Python の型とメソッドを理解するのに苦労しました。ただし、この複雑さは Python のせいではありません。コンピューターがテキストをエンコードする方法、特にテキストには複数のエンコーディングが存在するという事実が原因です。異なる一連のバイトが同じ一連の文字を表すことができる、使用されているエンコーディングに応じて。これにより、Python が文字列エンコーディングの要点をあなたから隠して、初心者の私が素朴に望んで期待していたように「自動的に適切なことを行う」ことができなくなります。
ASCII 以外の文字を含む可能性のあるテキスト データを Web から取得して使用することを含む大量のコードを作成する場合は、このトピックを徹底的に読み、十分に理解することをお勧めします。一般的および Python 固有のパースペクティブ。