Python中的open和codecs.open之间的区别

时间:2011-03-09 18:56:27

标签: python unicode codec

有两种方法可以在Python中打开文本文件:

f = open(filename)

import codecs
f = codecs.open(filename, encoding="utf-8")

codecs.open何时优于open

8 个答案:

答案 0 :(得分:72)

从Python 2.6开始,一个好的做法是使用io.open(),它也会使用encoding参数,就像现在过时的codecs.open()一样。在Python 3中,io.openopen()内置的别名。所以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.openio.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:

我可以轻松读取整个文件,有什么建议吗?