2013-07-06 12 views
10

Sto eseguendo il porting di un programma da Python2 (non conosco la versione esatta usata) a Python3.3 e aggiornando alcune cose, ma questo ciclo che controlla il esistenza di una serie di percorsi di file a cui si accede recentemente contro i file veri si blocca.L'esistenza del file Python verifica arresti anomali del loop - a meno che non aggiunga una dichiarazione di stampa

for index in range(story.recentFiles.GetCount()): 
    try: 
     if not os.path.exists(story.recentFiles.GetHistoryFile(index)): pass 
    except IOError: 
     self.RemoveRecentFile(story, index) 
     break 

L'accesso a un singolo file funziona bene, quindi è qualcosa che ha a che fare con il ciclo. Se passo il ciclo con un debugger, il codice funziona bene, ma se eseguo semplicemente l'applicazione, si blocca su un errore "python.exe ha smesso di rispondere".

La parte più strana, però, ha avuto modo di essere che quando aggiungo una dichiarazione di stampa prima della os.path.exists, funziona su un normale runthrough:

for index in range(story.recentFiles.GetCount()): 
    try: 
     print('test') # Why does printing this make it not crash?? 
     if not os.path.exists(story.recentFiles.GetHistoryFile(index)): pass 
    except IOError: 
     self.RemoveRecentFile(story, index) 
     break 

Che cosa è in su con quello? Suppongo che abbia qualche tipo di relazione con la velocità del loop rispetto ai tempi di accesso ai file o qualcosa di simile dato che passare lentamente permette di eseguirlo bene, ma onestamente non ho idea di quale sia il problema.

+0

Forse un bug con Python 3 :)? – Bharat

+5

Potrebbe essere un bug. Un'ipotesi più improbabile è che, se il programma non fa nulla, Windows pensa che non stia rispondendo. Ma se si stampa qualcosa, MS conosce il funzionamento dell'applicazione. Mi è successo una volta in VB.NET. – refi64

+3

Quali sono i file che sta accedendo?Esistono? Che cosa fanno quelle chiamate in "storia"? Puoi dare un esempio completo, eseguibile e riproducibile? – BrenBarn

risposta

0

Si sta interagendo con un codice C/C#/C++ scritto in modo scadente, quindi è difficile stabilire dove si trova l'errore.

Che sia scritto male è evidente dal modo in cui l'API ti fa recuperare gli elementi dell'elenco con una chiamata, piuttosto che usare semplicemente un indice.

Buona fortuna!

1

E 'difficile dire molto con maggiori dettagli, ma qui è una teoria: quando si aggiunge print, questo in realtà solleva un IOError (questo è possibile, come documented), che viene catturato, e os.path.exists(story.recentFiles.GetHistoryFile(index)) non eseguito , quindi il tuo programma non si blocca.

È possibile verificare questo con un test nel modo seguente (prima del codice citare):

try: 
    print('test') 
except IOError: 
    with open('ioerror_raised.txt', 'w'): 
     pass 

che creerà un file ioerror_raised.txt se il print sollevato IOError.

Questo potrebbe spiegare perché l'aggiunta di print esegue il codice.

(Se questo è il caso, allora os.path.exists(story.recentFiles.GetHistoryFile(index)) dovrebbe, ovviamente, eseguire il debug.)

1

si crea un elenco statico di indici validi (con range()) all'inizio del ciclo, ma si sta rimuovendo i file da l'elenco (RemoveRecentFile) all'interno del ciclo.

Quindi il problema potrebbe essere, che si avvia il ciclo con 10 file, rimosso un file (ad es. Indice 4) perché non è possibile accedervi, quindi provare ad accedere al file del 10 ° file (indice 9) che è non c'è più perché ti sei spostato 5-> 4, 6-> 5, 7-> 6, 8-> 7, 9-> 8

+0

d'accordo, penso che sia simile al bubbling nell'ottimizzazione del compilatore, in cui il compilatore aggiunge passaggi per abilitare il rivestimento delle tubature in modo tale che le informazioni possano essere reindirizzate correttamente a diversi stadi di diverse attività. – Mai

Problemi correlati