繁体   English   中英

Python中open和codecs.open的区别

[英]Difference between open and codecs.open in Python

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

f = open(filename)

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

codecs.open什么时候比open codecs.open可取?

从 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)时,您应该始终使用带有显式编码的io.open()带有显式编码的open()在 Python 中3. 这样做意味着您可以正确解码 Unicode,或者立即得到错误,从而更容易调试。

纯 ASCII“纯文本”是遥远过去的神话。 正确的英文文本使用卷曲引号、破折号、项目符号、€(欧元符号)甚至分音符 (¨)。 不要天真! (我们不要忘记 Facade 设计模式!)

因为纯 ASCII 不是一个真正的选择,所以没有显式编码的open()只能用于读取二进制文件。

就个人而言,我总是使用codecs.open除非有明确的确定需要使用open **。 原因是有很多次我被 utf-8 输入潜入我的程序所困扰。 “哦,我只知道它永远是 ascii”往往是一个经常被打破的假设。

根据我的经验,假设 'utf-8' 作为默认编码往往是一个更安全的默认选择,因为 ASCII 可以被视为 UTF-8,但反之则不然。 在这些情况下,当我真正知道输入是 ASCII 时,我仍然会使用codecs.open因为我坚信“显式优于隐式”

** - 在 Python 2.x 中,正如 Python 3 open对问题的评论所述,替换了codecs.open

在 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

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 字符的字节串。

当您需要打开具有特定编码的文件时,您将使用codecs模块。

我想codecs.open只是Python 2天的残余,当时内置 open 具有更简单的界面和更少的功能。 在 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.openbuilt-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)
  • 当您要加载二进制文件时,请使用f = io.open(filename, 'b')

  • 要打开文本文件,请始终使用带有显式编码的f = io.open(filename, encoding='utf-8')

然而,在python 3openio.open做同样的事情,可以代替使用。

注意: codecs.open计划在python 2.6 中引入后被弃用并由io.open取代。 如果代码需要与早期的 Python 版本兼容,我只会使用它。 有关 Python 中编解码器和 unicode 的更多信息,请参阅Unicode HOWTO

当您处理文本文件并希望透明编码和解码为 Unicode 对象时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM