有两种方法可以在Python中打开文本文件:
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中打开文本文件:
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
Answers:
从Python 2.6开始,一种好的做法是使用io.open()
,它也需要一个encoding
参数,例如now过时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()
改用。就像我问“何时使用扳手将钉子钉入墙壁?”。正确的答案是“用锤子”。
就个人而言,除非明确确定需要使用**,否则我总是使用。原因是有很多次我被utf-8输入偷偷摸摸地刺入我的程序。“哦,我只知道它永远是ascii”,这是一个经常被打破的假设。codecs.open
open
在我的经验中,假设将'utf-8'用作默认编码是一种比较安全的默认选择,因为ASCII可以视为UTF-8,但事实并非如此。在那些我确实确实知道输入是ASCII的情况下,我仍然会codecs.open
坚决相信“显式胜于隐式”。
**-在Python 2.x中,因为在Python 3中对问题状态的注释已open
替换codecs.open
open
有时可以很好地处理unicode集的UTF-8编码非拉丁字符,有时却无法正常工作……
io.open
我没有在python 2.7.5中看到的编码参数
io.open
接受encoding
和newline
参数并像Python 3一样解释它们。不同于codecs.open
,如果您尝试向其中写入(),则使用python 打开的文件甚至会在python 2.7中io.open
引发。用打开的文件将尝试隐式转换为,通常会导致s 混乱。TypeError: write() argument 1 must be unicode, not str
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和bytestring字符串与+
运算符连接在一起时,您将获得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
可使您非常轻松地执行后者。
请注意,您给它提供的是Unicode字符串,而不是可能包含非ASCII字符的字节字符串。
u''
在第一个示例中使用。这意味着我创建了一个unicode字符串,而不是字节字符串。这是两个示例之间的区别。在第二个示例中,我创建一个字节串并将其中之一写到文件中就可以了。如果您使用的是ASCII以外的字符,则unicode字符串不合适。
codecs.open
我想,这只是Python 2
内置开放式接口界面更简单,功能更少的时代的残余。在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的更多信息,请参见Unicode HOWTO。io.open
io.open
或以二进制模式打开文件codecs.open
?2. codecs.open
尚未弃用,请阅读链接到的页面上的讨论。
codecs.open()
,由于open()
获得了encoding
参数,在3.x 中已过时。