有两种方法可以在Python中打开文本文件:
f = open(filename)
和
import codecs
f = codecs.open(filename, encoding="utf-8")
codecs.open
何时优于open
?
答案 0 :(得分:72)
从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)时,您应始终使用{{1使用显式编码,或在Python 3中使用显式编码的io.open()
。这样做意味着您可以正确解码Unicode,或者立即获得错误,从而使调试更加容易。
纯ASCII“纯文本”是一个遥远过去的神话。正确的英文文本使用卷曲引号,em-dashes,子弹,€(欧元符号)甚至分音符(¨)。别天真! (让我们不要忘记Façade的设计模式!)
由于纯ASCII不是一个真正的选项,因此open()
没有明确的编码仅对读取二进制文件非常有用。
答案 1 :(得分:18)
就个人而言,我总是使用codecs.open
,除非明确确定需要使用open
**。原因是,当我被utf-8输入潜入我的程序时,已经被咬过很多次了。 “哦,我只知道它总是ascii”往往是一个经常被打破的假设。
假设'utf-8'作为默认编码在我的经验中往往是一个更安全的默认选择,因为ASCII可以被视为UTF-8,但反之则不然。在那些我确实知道输入是ASCII的情况下,我仍然codecs.open
,因为我是"explicit is better than implicit"的坚定信徒。
** - 在Python 2.x中,因为对Python 3 open
中的问题状态的评论取代了codecs.open
答案 2 :(得分:8)
在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字符的字节串。
答案 3 :(得分:6)
当您需要打开具有特定编码的文件时,您将使用codecs
模块。
答案 4 :(得分:5)
codecs.open
只是Python 2
时代的残余,当时内置的Open界面要简单得多,功能却更少。在Python 2中,内置的open
不带编码参数,因此,如果要使用二进制模式或默认编码以外的其他方式,则应使用codecs.open。
在Python 2.6
中,io模块帮助简化了事情。
根据官方documentation
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)
答案 5 :(得分:3)
当您使用文本文件并希望透明编码和解码为Unicode对象时。
答案 6 :(得分:2)
要加载二进制文件时,请使用
/party
/{partyid}
/messages
/{messageid} // You're missing this message id in the db
/text = "foo"
。
要打开文本文件,请始终使用f = io.open(filename, 'b')
进行显式编码。
在 python 3 中,f = io.open(filename, encoding='utf-8')
与open
的功能相同,可以代替使用。
注意::在{strong> python 2.6 中引入后,
io.open
计划成为deprecated,并由io.open
取代。如果代码需要与早期的python版本兼容,我只会使用它。有关python中的编解码器和unicode的更多信息,请参见Unicode HOWTO。
答案 7 :(得分:0)
我当时处于打开状态.asm文件并处理该文件的情况。
#https://docs.python.org/3/library/codecs.html#codecs.ignore_errors
#https://docs.python.org/3/library/codecs.html#codecs.Codec.encode
with codecs.open(file, encoding='cp1252', errors ='replace') as file:
我可以轻松读取整个文件,有什么建议吗?