Python 3用に構築されたPythonコードベースがあり、Python 3スタイルopen()をエンコードパラメーターとともに使用します。
https://github.com/miohtama/vvv/blob/master/vvv/textlineplugin.py#L47
with open(fname, "rt", encoding="utf-8") as f:
次に、このコードをPython 2.xにバックポートし、Python 2およびPython 3で動作するコードベースを作成します。
open()
の違いとエンコーディングパラメータの欠如を回避するための推奨戦略は何ですか?
バイト文字列をストリーミングするPython 3 open()
スタイルのファイルハンドラーがあるので、Python 2 open()
のように動作しますか?
Python 2.6および2.7のみをサポートする必要がある場合は、open
の代わりに io.open
を使用できます。 io
はPython 3の新しいioサブシステムであり、Python 2,6 ans 2.7にも存在します。 Python 2.6(3.0と同様)では、pythonに純粋に実装されており、非常に遅いため、ファイルの読み取りに速度が必要な場合、これは適切なオプションではありません。
速度が必要な場合、またはPython 2.5以前をサポートする必要がある場合は、代わりに codecs.open
を使用できます。また、エンコードパラメータがあり、io.open
と非常によく似ていますが、行末の処理方法が異なります。
open()
スタイルのファイルハンドラーを取得するには:open(filename, 'rb')
「バイナリ」を意味する「b」に注意してください。
おもう
from io import open
する必要があります。
1つの方法を次に示します。
with open("filename.txt", "rb") as f:
contents = f.read().decode("UTF-8")
これはトリックをするかもしれません:
import sys
if sys.version_info[0] > 2:
# py3k
pass
else:
# py2
import codecs
import warnings
def open(file, mode='r', buffering=-1, encoding=None,
errors=None, newline=None, closefd=True, opener=None):
if newline is not None:
warnings.warn('newline is not supported in py2')
if not closefd:
warnings.warn('closefd is not supported in py2')
if opener is not None:
warnings.warn('opener is not supported in py2')
return codecs.open(filename=file, mode=mode, encoding=encoding,
errors=errors, buffering=buffering)
その後、python3の方法でコードを保持できます。
newline
、closefd
、opener
などの一部のAPIは機能しないことに注意してください。
six
を使用している場合、これを試すことができます。これにより、最新のPython 3 APIを利用し、両方のPython 2/3で実行できます。
import six
if six.PY2:
# FileNotFoundError is only available since Python 3.3
FileNotFoundError = IOError
from io import open
fname = 'index.rst'
try:
with open(fname, "rt", encoding="utf-8") as f:
pass
# do_something_with_f ...
except FileNotFoundError:
print('Oops.')
また、Python 2サポートの放棄は、six
に関連するすべてを削除することです。