Python 如何解决;OSError:通知位置被next()调用禁用;

Python 如何解决;OSError:通知位置被next()调用禁用;,python,file-io,error-handling,next,Python,File Io,Error Handling,Next,我正在创建一个文件编辑系统,希望创建一个基于行的tell()函数,而不是基于字节的函数。此函数将在带有open(file)调用的“with循环”中使用。此函数是类的一部分,该类具有: self.f = open(self.file, 'a+') # self.file is a string that has the filename in it 以下是原始函数 (如果需要行和字节返回,它还有一个char设置): 我遇到的问题是,这会返回一个操作错误,它与系统如何迭代文件有关,但我不理解这个问

我正在创建一个文件编辑系统,希望创建一个基于行的tell()函数,而不是基于字节的函数。此函数将在带有open(file)调用的“with循环”中使用。此函数是类的一部分,该类具有:

self.f = open(self.file, 'a+')
# self.file is a string that has the filename in it
以下是原始函数 (如果需要行和字节返回,它还有一个char设置):


我遇到的问题是,这会返回一个操作错误,它与系统如何迭代文件有关,但我不理解这个问题。感谢所有能够提供帮助的人。

我有一个较旧版本的Python 3,我使用的是Linux而不是Mac,但我能够重新创建一些与您的错误非常接近的东西:

IOError:告诉位置被next()调用禁用
IO错误,不是操作系统错误,但在其他方面是相同的。奇怪的是,我无法使用您的
open('a+',…)
,但只能在读取模式下打开文件时使用:
open('r+',…)

更令人困惑的是,错误来自
\u io.TextIOWrapper
,一个似乎在Python的
\u pyio.py
文件中定义的类。。。我强调“出现”,因为:

  • 该文件中的
    TextIOWrapper
    具有类似
    \u的属性,告诉
    我无法访问调用自身的对象
    \u io.TextIOWrapper

  • \u pyio.py
    中的
    TextIOWrapper
    类不区分可读、可写或随机访问文件。要么两者都可以工作,要么两者都会引发相同的
    IOError

  • 无论如何,
    \u pyio.py
    文件中描述的
    TextIOWrapper
    类在迭代过程中禁用
    tell
    方法。这似乎就是你遇到的(评论是我的):

    def\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    #禁用tell方法。
    自欺欺人
    line=self.readline()
    如果不是直线:
    #我们已经到了文件的末尾。。。
    self.\u快照=无
    #…所以,让你回到过去。
    self.\u telling=self.\u seakable
    提出停止迭代
    回程线
    
    tell
    方法中,您几乎总是
    在迭代到达文件末尾之前中断
    ,使
    \u telling
    处于禁用状态(
    False
    ):

    重置
    的另一种方法是
    flush
    方法,但如果在迭代过程中调用该方法,也会失败:

    IOError:无法重建逻辑文件位置
    
    至少在我的系统上,解决这个问题的方法是在
    TextIOWrapper
    调用
    seek(0)
    ,这会将所有内容恢复到已知状态(并在交易中成功调用
    flush
    ):

    def tell(self,char=False):
    t、 lc=self.f.tell(),0
    self.f.seek(0)
    对于self.f中的行:
    如果t>=len(行):
    t-=len(直线)
    lc+=1
    其他:
    打破
    #重置文件迭代器,或稍后调用f.tell will
    #引发IOError或OSError:
    f、 搜索(0)
    如果是字符:
    返回信用证,t
    返回信用证
    
    如果这不是您的系统的解决方案,它至少可以告诉您从哪里开始寻找


    PS:你应该考虑总是返回行数和字符偏移量。返回完全不同类型的函数是很难处理的——调用者更容易扔掉她或她不需要的值。

    我不知道这是否是最初的错误,但如果你试图在一个文件的逐行迭代中调用f.tell(),你会得到同样的错误,就像这样:

    with open(path, "r+") as f:
      for line in f:
        f.tell() #OSError
    
    可由以下内容轻松替代:

    with open(path, mode) as f:
      line = f.readline()
      while line:
        f.tell() #returns the location of the next line
        line = f.readline()
    

    只是针对此问题的快速解决方法:

    无论如何,当您从一开始就迭代文件时,只需使用专用变量跟踪您的位置:

    file_pos = 0
    with open('file.txt', 'rb') as f:
        for line in f:
            # process line
            file_pos += len(line)
    

    现在
    file\u pos
    将永远是
    file.tell()
    将告诉您的内容。请注意,这仅适用于ASCII文件,因为tell和seek使用字节位置。以行为基础,将字符串从字节转换为unicode字符串很容易

    我遇到了同样的错误:OSError:telling position被next()调用禁用,并通过在打开文件时添加“rb”模式解决了这个问题。

    如果没有看到其他类,很难回答。(我无法仅使用函数在Linux上复制它。)您可能需要阅读,这可以为您(和我们)提供一些附加信息。我的第一个问题是,因为这是一个操作系统错误:你的操作系统是什么?另外(可能相关):为什么/如何在其中查找?我以附加模式打开它,因为在创建实例之前,假定该文件不存在。(如您所知,我确信,“a”模式会在文件不存在时创建该文件)。我希望能够在代码中节省空间,以便检查文件是否存在。我的操作系统是MacOSXYosemite,但我认为这与苹果无关。非常感谢你的帮助!我的问题是,在文件迭代过程中(逐行)无法调用(内置)tell()方法。我找到了解决这个问题的方法,你的回答真的很有帮助。再次感谢@BrandonGomes:你介意和我分享你的解决方案吗?对不起@marscher,我没有这个代码了。它来自一台旧电脑。我认为答案是存储一些关于文件迭代器的元数据。你可以随时重写下一个函数。这是最方便的方法!这是一个多么愚蠢的问题,谢谢:)在py3中,由于“rb”行是您所期望的(包括
    \r\n
    中的行终止符)-因此这对于倒带到行的开始非常有效-漂亮!
    file_pos = 0
    with open('file.txt', 'rb') as f:
        for line in f:
            # process line
            file_pos += len(line)