考虑这个非常简单的示例。
import codecs
from io import BytesIO
string = b"""# test comment
Some line without comment
# another comment
"""
reader = codecs.getreader("UTF-8")
stream = reader(BytesIO(string))
lines = []
while True:
# get current position
position = stream.tell()
# read first character
char = stream.read(1)
# return cursor to start
stream.seek(position, 0)
# end of stream
if char == "":
break
# line is not comment
if char != "#":
lines.append(stream.readline())
continue
# line is comment. Skip it.
stream.readline()
print(lines)
assert lines == ["Some line without comment\n"]
我正在尝试从StreamReader逐行读取,如果该行以#
开头,则将其跳过,否则会将其存储在列表中。但是,当我使用seek()
方法时,会有一些奇怪的行为。 seek()
和readline()
似乎不合作,将光标移到很远的地方。结果列表为空。
我当然可以用不同的方式来做。但是,正如我上面所写的那样,这是一个非常简单的示例,它可以帮助我理解事情的协同作用。
我使用Python 3.5。
答案 0 :(得分:5)
您不想使用codecs
流阅读器。由于io
module已被serious calls for the stream readers to be deprecated取代,这是一种更健壮和更快的实现,因此它们是实现分层I / O以处理文本的编码的较旧的,过时的尝试。已经有io.TextIOWrapper()
object。
您真的想用https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise/all代替对codecs.getreader()
的使用:
import codecs
from io import BytesIO, TextIOWrapper
string = b"""# test comment
Some line without comment
# another comment
"""
stream = TextIOWrapper(BytesIO(string))
此时while
循环开始工作,lines
最终以['Some line without comment\n']
结束。
您也不需要在此处使用搜索或tell()
。您可以直接在文件对象(包括TextIOWrapper()
对象)上循环:
lines = []
for line in stream:
if not line.startswith('#'):
lines.append(line)
甚至:
lines = [l for l in stream if not l.startswith('#')]
如果您担心TextIOWrapper()
包装器对象在不再需要包装器时关闭基础流,则只需先 detach 包装器:
stream.detach()
答案 1 :(得分:1)
只要交换
,您的代码就可以使用reader = codecs.getreader("UTF-8")
stream = reader(BytesIO(string))
使用
stream = BytesIO(string)
编辑:如果要使用StreamReader,则可以使用tell()
摆脱重新定位,因为stream.read()
和stream.readline()
足以重新定位。换句话说,在您当前的代码中,您将重新定位两次。
循环中更改的代码:
# read first character
char = stream.read(1)
# end of stream
if char == "":
break
# line is not comment
if char != "#":
lines.append(char + stream.readline())
continue
# line is comment. Skip it.
stream.readline()
请注意对lines.append()
的更改