Ho una vecchia versione di Python 3, e io sono su Linux invece di un Mac, ma sono stato in grado di ricreare qualcosa di molto vicino al vostro errore:
IOError: telling position disabled by next() call
un errore IO, non un errore OS, ma per il resto lo stesso. Stranamente, non ho potuto causarlo usando il tuo open('a+', ...)
, ma solo aprendo il file in modalità lettura: open('r+', ...)
.
ulteriormente le cose confusionaria è che l'errore viene da _io.TextIOWrapper
, una classe che sembra da definire nel file di Python _pyio.py
... sottolineo "Viene visualizzato", perché:
Il TextIOWrapper
in quel il file ha attributi come _telling
che non riesco ad accedere all'oggetto che si chiama se stesso _io.TextIOWrapper
.
La classe TextIOWrapper
in _pyio.py
non fa alcuna distinzione tra file leggibili, scrivibili o ad accesso casuale. O entrambi dovrebbero funzionare, o entrambi dovrebbero aumentare lo stesso IOError
.
Indipendentemente, la classe TextIOWrapper
come descritto nel _pyio.py
fascicolo disabilita il metodo tell
mentre l'iterazione è in corso.Questo sembra essere quello che si sta eseguendo in (i commenti sono miei):
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
nel metodo tell
, è quasi sempre fuori break
dell'iterazione prima che raggiunga il fine del file, lasciando _telling
disabilitato (False
):
Un altro modo per ripristinare _telling
è il metodo flush
, ma anche non è riuscito se chiamato mentre l'iterazione era in corso:
IOError: can't reconstruct logical file position
Il modo per aggirare questo, almeno sul mio sistema, è quello di chiamata seek(0)
sul TextIOWrapper
, che restituisce tutto a uno stato noto (e con successo le chiamate flush
in giunta):
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
Se questo non è il soluzione per il tuo sistema, potrebbe almeno dirti dove iniziare a cercare.
PS: è necessario considerare sempre restituendo sia il numero di riga che l'offset di carattere. Le funzioni che possono restituire tipi completamente diversi sono difficili da gestire --- è molto più semplice per il chiamante buttare via il valore di lei o lei non ne ha bisogno.
Difficile rispondere senza vedere il resto della classe. (Non riuscivo a riprodurlo su Linux usando solo le funzioni.) Potresti voler leggere su [Attributi di OSError'] (https://docs.python.org/3/library/exceptions.html#OSError) , che può darti (e noi) alcune informazioni aggiuntive. La mia prima domanda sarebbe, poiché si tratta di un errore _OS_: qual è il tuo sistema operativo? Inoltre (possibilmente correlato): Perché/come stai [aprendo il file in modalità append] (https://docs.python.org/3/library/functions.html#open) e poi cerchiamo di aggirarlo al suo interno? –
Lo sto aprendo in modalità append perché, si presume che il file sia inesistente prima che l'istanza venga creata. (come sai, sono sicuro che la modalità 'a' crea il file se non esiste ancora). Volevo essere in grado di risparmiare spazio nel codice per avere un controllo se il file esisteva. Il mio sistema operativo è Mac OS X Yosemite, ma non penso che abbia a che fare con Apple. –