per*_*oud 5 python utf-8 readline codec python-2.7
我有一个普通的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%
Run Code Online (Sandbox Code Playgroud)
系统:
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
Run Code Online (Sandbox Code Playgroud)
当然它适用于常规open.如果我删除该"utf-8"选项,它也有效.还有什么63意思?这就像是第3行的中间部分.我不明白.
发现你的问题:
当传递一个编码时,codecs.open返回一个StreamReaderWriter,它实际上只是一个包装器(不是它的子类;它是"由...组成",而不是继承)StreamReader和StreamWriter.问题是:
StreamReaderWriter提供"正常" read方法(也就是说,它需要一个size参数,就是这样)StreamReader.read方法,其中size参数只是提示要读取的字节数,而不是限制; 在第二个参数,chars是一个严格的限制,但StreamReaderWriter从来没有经过这样的说法沿(不接受)size提示,但没有使用上限chars,如果StreamReader有缓冲数据,并且它足够大以匹配size提示StreamReader.read盲目地返回缓冲区的内容,而不是基于size提示以任何方式限制它(毕竟,只chars强加最大返回大小)API的API StreamReader.read和size/ 的含义chars是这里唯一记录的内容; 这一事实codecs.open返回StreamReaderWriter不是合同,也不是事实StreamReaderWriter包装StreamReader,我只是用ipython的??魔法读取源代码codecs模块来验证此行为.但是有记录与否,这就是它正在做的事情(随意阅读源代码StreamReaderWriter,它是所有Python级别,所以很容易).
最好的解决办法是切换到io.open,这是在每一个标准的情况下,更快,更正确的是(codecs.open支持怪人编解码器不转换之间bytes[的Py2 str]和str[的Py2 unicode],而是处理str到str或bytes到bytes编码,但是这是一个令人难以置信有限的用例;大多数时候,你在bytes和之间进行转换str.您需要做的就是导入io而不是codecs,并将codecs.open行更改为:
f = io.open("test.py", encoding="utf-8")
Run Code Online (Sandbox Code Playgroud)
其余代码可以保持不变(并且可能会更快地启动).
作为替代方案,你可以明确地绕过StreamReaderWriter来获取StreamReader的read方法,直接通过限制参数,例如变化:
c = f.read(1)
Run Code Online (Sandbox Code Playgroud)
至:
# Pass second, character limiting argument after size hint
c = f.reader.read(6, 1) # 6 is sort of arbitrary; should ensure a full char read in one go
Run Code Online (Sandbox Code Playgroud)
我怀疑Python的错误#8260,涵盖交织readline和read上codecs.open创建文件对象,在这里适用,正式,它是"固定"的,但如果你读了评论,修复是不完全的(并且可能无法来完成给定的记录API); 任意奇怪的组合,read并将readline能够打破它.
再次,只是使用io.open; 只要您使用的是Python 2.6或更高版本,它就可以使用,而且它只是更好.
| 归档时间: |
|
| 查看次数: |
1502 次 |
| 最近记录: |