问题:向后移植将Python 3 open(encoding =“ utf-8”)移植到Python 2
我有一个为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()
吗?
回答 0
1.在Python 2中获取编码参数:
如果您只需要支持Python 2.6和2.7,则可以使用io.open
代替open
。io
是Python 3的新io子系统,它也存在于Python 2,6 ans 2.7中。请注意,在Python 2.6(以及3.0)中,它是完全在python中实现的,并且运行速度非常慢,因此,如果您需要快速读取文件,则不是一个好的选择。
如果需要速度,并且需要支持Python 2.6或更早版本,则可以codecs.open
改用。它也有一个编码参数,io.open
除了它以不同的方式处理行尾之外,它与之非常相似。
2.要获取open()
可流字节串的Python 3 样式文件处理程序,请执行以下操作:
open(filename, 'rb')
注意“ b”,意思是“二进制”。
回答 1
我认为
from io import open
应该做。
回答 2
这是一种方法:
with open("filename.txt", "rb") as f:
contents = f.read().decode("UTF-8")
回答 3
这可能会达到目的:
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
不工作
回答 4
如果您使用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
。