Backporting Python 3 open (encoding = "utf-8" ) на Python 2
У меня есть кодовая база Python, созданная для Python 3, которая использует стиль 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()
?
Ответы
Ответ 1
1. Чтобы получить параметр кодирования в Python 2:
Если вам нужно только поддерживать Python 2.6 и 2.7, вы можете использовать io.open
вместо open
. io
является новой подсистемой io для Python 3, и она также существует в Python 2,6 и 2.7. Имейте в виду, что в Python 2.6 (а также 3.0) он реализован исключительно на python и очень медленный, поэтому, если вам нужна скорость чтения файлов, это не очень хороший вариант.
Если вам нужна скорость и вам нужна поддержка Python 2.6 или более ранней версии, вы можете использовать codecs.open
. Он также имеет параметр кодирования и очень похож на io.open
, за исключением того, что он по-разному обрабатывает окончания строк.
2. Чтобы получить обработчик файлов в стиле Python 3 open()
, который передает потоковые строки:
open(filename, 'rb')
Обратите внимание на "b", что означает "двоичный".
Ответ 2
Я думаю,
from io import open
.
Ответ 3
Здесь один из способов:
with open("filename.txt", "rb") as f:
contents = f.read().decode("UTF-8")
Ответ 4
Это может сделать трюк:
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.
Обратите внимание, что некоторые API, такие как newline
, closefd
, opener
не работают
Ответ 5
Если вы используете six
, вы можете попробовать это, используя последний API Python 3 и может работать как в 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
.