Pythonでテキストファイルを開く方法は2つあります。
f = open(filename)
そして
import codecs
f = codecs.open(filename, encoding="utf-8")
いつがcodecs.open
望ましいopen
ですか?
codecs.open()
廃止されたリンクはありますか?私はこれをpython3のドキュメントでは考えていません:docs.python.org/3.7/library/codecs.html
Pythonでテキストファイルを開く方法は2つあります。
f = open(filename)
そして
import codecs
f = codecs.open(filename, encoding="utf-8")
いつがcodecs.open
望ましいopen
ですか?
codecs.open()
廃止されたリンクはありますか?私はこれをpython3のドキュメントでは考えていません:docs.python.org/3.7/library/codecs.html
回答:
Python 2.6以降では、を使用することをお勧めしますio.open()
。これもencoding
、現在は使用されなくなったのように、引数を取りますcodecs.open()
。Python 3では、io.open
はopen()
組み込みのエイリアスです。そのためio.open()
、Python 2.6以降のすべてのバージョン(Python 3.4を含む)で動作します。ドキュメントを参照してください: http //docs.python.org/3.4/library/io.html
ここで、元の質問について:Python 2でテキスト(「プレーンテキスト」、HTML、XML、JSONを含む)を読み取るときは、常にio.open()
明示的なエンコーディングで使用する必要があります。open()
、Python 3で明示的なエンコーディングを使用する必要があります。そうすることで、正しく取得できますUnicodeをデコードするか、すぐにエラーを取得して、デバッグをはるかに簡単にします。
純粋なASCIIの「プレーンテキスト」は、はるか昔の神話です。適切な英語のテキストでは、中かっこ、エムダッシュ、箇条書き、€(ユーロ記号)、さらには分音記号(¨)を使用します。ナイーブにならないでください!(そして、ファサードのデザインパターンを忘れないでください!)
純粋なASCIIは実際のオプションではないためopen()
、明示的なエンコーディングなしでバイナリファイルを読み取る場合にのみ役立ちます。
io.open()
ますopen()
。テキストに使用し、バイナリのみに使用してください。つまり、それcodecs.open()
はまったく好ましくないということです。
open
ありcodecs.open
、具体的には、後者が前者よりも好ましい場合です。言及ほど多くcodecs.open
ない答えはその質問に答えることができません。
codecs.open()
使用することが正しいという前提で)、いつ使用するかについての「正しい」回答はありません。答えはio.open()
代わりに使用することです。「レンチを使って釘を壁に打ち込む必要があるのはいつ?」と尋ねるようなものです。正解は「ハンマーを使う」です。
個人的には、** を使用する必要性が明確に識別されていない限り、常に使用codecs.open
しますopen
。その理由は、utf-8入力をプログラムに忍び込ませることで私が噛まれたことが何度もあったからです。「ああ、私はいつもそれがアスキーであることを知っている」というのは、しばしば壊れてしまう仮定です。
ASCIIはUTF-8として扱うことができるため、私の経験では、デフォルトのエンコーディングとして「utf-8」を使用する方が安全なデフォルトの選択になる傾向がありますが、その逆は当てはまりません。そして、私が入力がASCIIであることを本当に知っているような場合でもcodecs.open
、私は「明示的なものは暗黙的なものより優れている」と確信しているため、私はまだそうしています。
**-Python 2.xでは、質問へのコメントがPython 3にopen
置き換わったためcodecs.open
open
は、ユニコードセットのUTF-8エンコードされた非ラテン文字をうまく処理できることがあり、誤って失敗することがあります...
io.open
私がpython 2.7.5で見ることができるものからエンコードパラメータを取得しません
io.open
受け入れencoding
、newline
それらをPython 3と同様に解釈します。異なりcodecs.open
、で開かれたファイルがio.open
発生しますTypeError: write() argument 1 must be unicode, not str
、あなたが書き込みをしようとした場合でも、Pythonの2.7でstr
(bytes
それまで)。で開いたファイルは、codecs.open
代わりにへの暗黙の変換を試みunicode
、しばしばを混乱させUnicodeDecodeError
ます。
Python 2には、Unicode文字列とバイト文字列があります。バイト文字列のみを使用する場合は、で開いたファイルを読み書きできます。open()
。結局のところ、文字列は単なるバイトです。
たとえば、Unicode文字列があり、次のような場合に問題が発生します。
>>> example = u'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
したがって、ここでは明らかに、utf-8でUnicode文字列を明示的にエンコードするか、 codecs.open
透過的にそれを行うためにします。
バイト文字列のみを使用している場合は問題ありません。
>>> example = 'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
>>>
Unicodeとバイト文字列を+
演算子で連結すると、Unicode文字列が得られるため、これよりも複雑になります。それに噛まれやすい。
また、codecs.open
ASCII以外の文字が渡されるバイト文字列は好きではありません。
codecs.open('test', 'w', encoding='utf-8').write('Μου αρέσει')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/codecs.py", line 691, in write
return self.writer.write(data)
File "/usr/lib/python2.7/codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)
入力/出力用の文字列に関するアドバイスは、通常「できるだけ早くUnicodeに変換し、できるだけ遅くバイト文字列に戻す」です。使用するcodecs.open
すると、後者を非常に簡単に実行できます。
ASCII以外の文字が含まれる可能性のあるバイト文字列ではなく、Unicode文字列を指定するように注意してください。
u''
最初の例でのの使用に注意してください。これは、バイト文字列ではなくUnicode文字列を作成したことを意味します。これが2つの例の違いです。2番目の例では、バイト文字列を作成し、それらの1つをファイルに書き込んで問題ありません。ASCII以外の文字を使用している場合、Unicode文字列は適切ではありません。
codecs.open
はPython 2
、組み込みのopenのインターフェースがはるかにシンプルで機能が少なかった時代の名残だと思います。Python 2では、組み込みopen
はエンコーディング引数を取りません。そのため、バイナリモードまたはデフォルトのエンコーディング以外のものを使用する場合は、codecs.openが使用されることになっています。
ではPython 2.6
、IOモジュールは物事が少し簡単にするための援助に来ました。公式ドキュメントによると
New in version 2.6.
The io module provides the Python interfaces to stream handling.
Under Python 2.x, this is proposed as an alternative to the
built-in file object, but in Python 3.x it is the default
interface to access files and streams.
そうは言っても、codecs.open
現在のシナリオで私が考えることができる唯一の使用は、下位互換性のためです。他のすべてのシナリオ(Python 2.6未満を使用している場合を除く)では、を使用することをお勧めしますio.open
。もPython 3.x
io.open
同じですbuilt-in open
注意:
との間にも構文上の違いがcodecs.open
ありio.open
ます。
codecs.open
:
open(filename, mode='rb', encoding=None, errors='strict', buffering=1)
io.open
:
open(file, mode='r', buffering=-1, encoding=None,
errors=None, newline=None, closefd=True, opener=None)
codecs.open
、io.open
異なるタイプのオブジェクトを返します。また、codecs.open
常にバイナリモードでファイルを操作します。
バイナリファイルをロードする場合は、を使用します
f = io.open(filename, 'b')
。
テキストファイルを開くには、常にf = io.open(filename, encoding='utf-8')
明示的なエンコーディングで使用します。
python 3しかし、open
同じことをしio.open
て、代わりに使用することができます。
注:
codecs.open
は、Python 2.6での導入後に廃止され、置き換えられる予定です。コードが以前のバージョンのpythonと互換性が必要な場合にのみ使用します。Pythonのコーデックとユニコードの詳細については、Unicode HOWTOを参照してください。io.open
io.open
またはでバイナリモードでファイルを開けないのはなぜcodecs.open
ですか?2. codecs.open
は非推奨ではありません。リンク先のページの説明をお読みください。
codecs.open()
ため、3.xでは廃止されていることに注意してください。open()
encoding