Ich habe eine ältere Version von Python 3, und ich bin auf Linux anstelle eines Mac, aber ich war in der Lage, etwas sehr nah an Ihre Fehler zu erstellen:
IOError: telling position disabled by next() call
Ein IO Fehler, kein OS Fehler, aber ansonsten gleich. Bizarr genug, ich könnte es nicht mit Ihrem open('a+', ...)
verursachen, aber nur beim Öffnen der Datei im Lesemodus: open('r+', ...)
.
Weitere muddling Dinge ist, dass der Fehler von _io.TextIOWrapper
kommt, eine Klasse, die erscheint in Python _pyio.py
Datei definiert werden ... Ich betone "erscheint", denn:
Die TextIOWrapper
, dass Datei hat Attribute wie _telling
, auf die ich nicht zugreifen kann auf dem was-auch-ist-Objekt ruft sich selbst _io.TextIOWrapper
.
Die TextIOWrapper
Klasse in _pyio.py
macht keinen Unterschied zwischen lesbar, beschreibbar oder Random-Access-Dateien. Entweder sollten beide funktionieren, oder beide sollten das gleiche IOError
auslösen.
Unabhängig davon, die als Klasse TextIOWrapper
in der _pyio.py
Datei beschrieben deaktiviert die tell
Verfahren während der Iteration läuft.Dies scheint zu sein, was Sie laufen in (Kommentare sind ich):
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
In Ihrer tell
Methode, Sie fast immer break
aus der Iteration, bevor sie das Ende der Datei erreicht, so dass _telling
deaktiviert (False
):
Eine andere Möglichkeit ist die _telling
flush
Methode zurückgesetzt, aber es auch nicht genannt, wenn während der Iteration im Gange war:
IOError: can't reconstruct logical file position
Die Art und Weise, um diesen, zumindest auf meinem System ist zu Anruf seek(0)
auf den TextIOWrapper
, die alles in einen bekannten Zustand wieder her (und erfolgreich ruft flush
im Handel):
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
Wenn das nicht der ist Lösung für Ihr System, könnte es Ihnen zumindest sagen, wo Sie anfangen zu suchen.
PS: Sie sollten immer betrachten, die sowohl die Zeilennummer als auch den Zeichenoffset zurückgibt. Funktionen, die ganz unterschiedliche Typen zurückgeben können, sind schwer zu handhaben --- es ist viel einfacher für den Anrufer, einfach den Wert wegzuwerfen, den er oder sie nicht benötigt.
Schwer zu beantworten, ohne den Rest Ihrer Klasse zu sehen. (Ich konnte es unter Linux nicht nur mit Funktionen reproduzieren.) Vielleicht möchten Sie sich über [OSError's Attribute] informieren (https://docs.python.org/3/library/exceptions.html#OSError) , die Ihnen (und uns) einige zusätzliche Informationen geben können. Meine erste Frage wäre, da dies ein _OS_ Fehler ist: Was ist dein Betriebssystem? Auch (möglicherweise verwandt): Warum/wie [öffnen Sie die Datei im Append-Modus] (https://docs.python.org/3/library/functions.html#open) und suchen Sie sich dann darin herum? –
Ich öffne es im Append-Modus, weil angenommen wird, dass die Datei nicht existent ist, bevor die Instanz erstellt wird. (Wie Sie sicher wissen, erstellt ein 'Modus' die Datei, wenn sie noch nicht existiert). Ich wollte Platz im Code sparen, um zu überprüfen, ob die Datei existiert. Mein Betriebssystem ist Mac OS X Yosemite, aber ich denke nicht, dass es mit Apple zu tun hat. –