Bra*_*mes 15 python error-handling file-io next
我正在创建一个文件编辑系统,并希望创建一个基于行的tell()函数而不是基于字节的函数.此函数将在打开(文件)调用的"with循环"内使用.此函数是具有以下内容的类的一部分:
self.f = open(self.file, 'a+')
# self.file is a string that has the filename in it
Run Code Online (Sandbox Code Playgroud)
以下是原始函数(如果您想要行和字节返回,它还有一个char设置):
def tell(self, char=False):
t, lc = self.f.tell(), 0
self.f.seek(0)
for line in self.f:
if t >= len(line):
t -= len(line)
lc += 1
else:
break
if char:
return lc, t
return lc
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,这会返回一个OSError,它与系统如何迭代文件有关,但我不明白这个问题.感谢任何能提供帮助的人.
小智 22
我不知道这是不是原始错误,但如果你尝试在文件的逐行迭代中调用f.tell(),你可以得到相同的错误:
with open(path, "r+") as f:
for line in f:
f.tell() #OSError
Run Code Online (Sandbox Code Playgroud)
可以很容易地用以下代替:
with open(path, mode) as f:
line = f.readline()
while line:
f.tell() #returns the location of the next line
line = f.readline()
Run Code Online (Sandbox Code Playgroud)
Kev*_*ase 12
我有一个旧版本的Python 3,我在Linux而不是Mac,但我能够重新创建一些非常接近你错误的东西:
IOError: telling position disabled by next() call
Run Code Online (Sandbox Code Playgroud)
一个IO错误,而不是一个操作系统错误,但在其他方面是相同的.奇怪的是,我不能使用你的open('a+', ...),但只有在读取模式下打开文件时:open('r+', ...).
进一步混淆的是错误来自于_io.TextIOWrapper一个似乎在Python _pyio.py文件中定义的类......我强调"出现",因为:
该TextIOWrapper文件中的属性具有类似于_telling我无法在调用自身的任何对象上访问的属性_io.TextIOWrapper.
本TextIOWrapper类_pyio.py不作可读,可写,或随机存取文件之间的任何区别.要么两者都应该起作用,要么两者都应该提高IOError.
无论如何,文件中TextIOWrapper描述的类在迭代进行时禁用该方法.这似乎是你遇到的(评论是我的):_pyio.pytell
def __next__(self):
# Disable the tell method.
self._telling = False
line = self.readline()
if not line:
# We've reached the end of the file...
self._snapshot = None
# ...so restore _telling to whatever it was.
self._telling = self._seekable
raise StopIteration
return line
Run Code Online (Sandbox Code Playgroud)
在你的tell方法中,你几乎总是break在它到达文件末尾之前离开迭代,离开_tellingdisabled(False):
另一种重置方法_telling是flush方法,但如果在迭代进行过程中调用它也会失败:
IOError: can't reconstruct logical file position
Run Code Online (Sandbox Code Playgroud)
解决这个问题的办法,至少我的系统上,就是要叫seek(0)上了TextIOWrapper,这一切都恢复到已知状态(成功调用flush在讨价还价中):
def tell(self, char=False):
t, lc = self.f.tell(), 0
self.f.seek(0)
for line in self.f:
if t >= len(line):
t -= len(line)
lc += 1
else:
break
# Reset the file iterator, or later calls to f.tell will
# raise an IOError or OSError:
f.seek(0)
if char:
return lc, t
return lc
Run Code Online (Sandbox Code Playgroud)
如果这不是您系统的解决方案,它至少可以告诉您从哪里开始寻找.
PS:您应该考虑始终返回行号和字符偏移量.可以返回完全不同类型的函数很难处理 - 调用者只需丢弃她或她不需要的值就容易多了.
只是这个问题的快速解决方法:
无论如何,当您从头开始迭代文件时,只需使用专用变量跟踪您的位置:
file_pos = 0
with open('file.txt', 'rb') as f:
for line in f:
# process line
file_pos += len(line)
Run Code Online (Sandbox Code Playgroud)
现在file_pos将永远是,file.tell()会告诉你什么。请注意,这仅适用于 ASCII 文件,因为告诉和寻找字节位置的工作。虽然以行为基础工作,但将字符串从字节转换为 unicode 字符串很容易。
| 归档时间: |
|
| 查看次数: |
10233 次 |
| 最近记录: |