考虑这个非常简单的例子.
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"]
Run Code Online (Sandbox Code Playgroud)
我试图从StreamReader逐行读取,如果行开头#
我跳过它,否则我将它存储在列表中.但是当我使用seek()
方法时有一些奇怪的行为.似乎seek()
并且readline()
不合作并将光标移动到远处的某个地方.结果列表为空.
当然,我可以用不同的方式做到这一点.但正如我上面所写,这是一个非常简单的例子,它可以帮助我理解事物如何协同工作.
我使用Python 3.5.
您不想使用codecs
流阅读器.它们是一种较旧的,过时的尝试,用于实现分层I/O以处理文本的编码和解码,因为它被io
模块取代,实现得更加强大和快速.有人严肃地呼吁不要弃用流阅读器.
你真的想codecs.getreader()
用io.TextIOWrapper()
对象替换你的使用:
import codecs
from io import BytesIO, TextIOWrapper
string = b"""# test comment
Some line without comment
# another comment
"""
stream = TextIOWrapper(BytesIO(string))
Run Code Online (Sandbox Code Playgroud)
在这一点上while
循环工作并lines
最终成为['Some line without comment\n']
.
您也不需要使用搜索或tell()
此处.您可以直接循环遍历文件对象(包括TextIOWrapper()
对象):
lines = []
for line in stream:
if not line.startswith('#'):
lines.append(line)
Run Code Online (Sandbox Code Playgroud)
甚至:
lines = [l for l in stream if not l.startswith('#')]
Run Code Online (Sandbox Code Playgroud)
如果您担心在TextIOWrapper()
不再需要包装器时关闭底层流的包装器对象,则首先分离包装器:
stream.detach()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
283 次 |
最近记录: |