【发布时间】:2018-03-08 08:16:29
【问题描述】:
我有一个纯 ASCII 文件。当我尝试使用codecs.open(..., "utf-8") 打开它时,我无法读取单个字符。 ASCII是UTF-8的一个子集,为什么codecs不能以UTF-8模式打开这样的文件呢?
# test.py
import codecs
f = codecs.open("test.py", "r", "utf-8")
# ASCII is supposed to be a subset of UTF-8:
# http://www.fileformat.info/info/unicode/utf8.htm
assert len(f.read(1)) == 1 # OK
f.readline()
c = f.read(1)
print len(c)
print "'%s'" % c
assert len(c) == 1 # fails
# max% p test.py
# 63
# '
# import codecs
#
# f = codecs.open("test.py", "r", "utf-8")
#
# # ASC'
# Traceback (most recent call last):
# File "test.py", line 15, in <module>
# assert len(c) == 1 # fails
# AssertionError
# max%
系统:
Linux max 4.4.0-89-generic #112~14.04.1-Ubuntu SMP Tue Aug 1 22:08:32 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
当然,它适用于普通的open。如果我删除 "utf-8" 选项,它也可以工作。还有63 是什么意思?这就像第三行的中间。没看懂。
【问题讨论】:
-
还打印出字符本身,而不仅仅是字符的长度和字节码。
-
长度表明它也包括之前的 readline 结果;有趣。
-
好吧,至少我可以在我的 Mac 上用 Python 版本 2.7.10、2.7.13 和 3.6.2 重现这个。
len(c)对我来说在所有情况下都是 59。 -
旁注:从不使用
codecs.open。它以奇怪的方式存在缺陷(正如@Evert 所指出的,它必须以二进制模式打开文件,这会产生各种副作用)。试试usingio.openinstead(它与Py3 上的普通open相同,并在Py2 上提供相同的接口),并且比codecs.open(基本上已弃用)更快更正确。我怀疑你的问题会消失。 -
@personal_clown:
codecs.open处于一种奇怪的状态。它严格不如io.open,除非在一些非常不寻常的情况下(字节字节编解码器,如ROT13和十六进制,而不是标准字节Unicode编解码器)。由于怪异的用例,他们一直不愿意正式弃用它,但如果你检查 Python 错误跟踪器,它通常被称为伪弃用。 PEP 400 includes a bunch of reasons 为什么StreamReader/StreamWriter/StreamReaderWriter(codecs.open创建的)坏了。
标签: python python-2.7 utf-8 readline codec