10
votes

L'existence du fichier Python vérifie des accidents de boucle - sauf si j'ajoute une déclaration d'impression

Je porte un programme de Python2 (ne connais pas la version exacte utilisée) à Python3.3 et à la mise à jour de quelques éléments, mais cette boucle qui vérifie l'existence d'un ensemble de chemins de fichiers récemment accessibles contre les fichiers réels Des accidents.

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


12 commentaires

Peut-être un bug avec Python 3 :)?


Ce pourrait être un bug. Une hypothèse plus improbable est que, si le programme ne fait rien, Windows pense qu'il ne répond pas. Mais si vous imprimez quelque chose, MM connaît le fonctionnement de l'application. Cela m'est arrivé une fois dans vb.net.


Quels sont les fichiers qu'il accède? Existe-t-ils? Qu'est-ce que ces appellent dans histoire faire? Pouvez-vous donner un exemple complet, exécutable et reproductible?


@Brenbarn: Ce sont des fichiers binaires simples; Ils existent et les appels dans histoire ne font que renvoyer un chemin de chaîne.


Quelle est la taille de la plage (story.recentfiles.getcount ()) ?


@Brenbarn: Cependant, de nombreux fichiers récemment consultés sont (je l'ai changé). Normalement quelque chose de petit, 2 ou 3 - ce n'est pas un problème d'index de quelque sorte que je puisse dire. J'ai parcouru et double vérifié. C'est un mystère pour moi!


@ WaySpurr-Chen: Avez-vous un message d'erreur imprimé dans un terminal? Je pense avoir vu des programmes suspendus à Windows à cause de cela ...


@El: Nope, c'est la pire partie; Rien ne va au terminal du tout, et si je passe dans le programme, il s'exécute sans problème.


@ WaySpurr-Chen: Si je me souviens bien, j'ai vu un phénomène similaire avec un programme C sous Windows. Le fait que impression et en progressant le programme change le comportement du programme me permet de me demander si cela n'est pas lié au terminal d'une manière ou d'une autre. Vous voudrez peut-être essayer d'exécuter votre code avec un autre programme terminal.


Pouvez-vous mettre tous les chemins du fichier récent dans une liste et faire sur cette liste? Il serait intéressant de savoir s'il se bloque dans la boucle ou lors de la récupération des chemins de fichiers récents.


Changez votre os.path.exists à os.stat () (c'est ce que existe fait quand même). Voyez si vous vous plantiez toujours.


Quelle fonction lance ioerror et pourquoi?


4 Réponses :


0
votes

Vous êtes en interface avec un code C / C # / C ++ mal écrit, il est donc difficile de faire un point d'épingle lorsque l'erreur est.

Il est mal écrit est évident de la manière dont l'API vous fait récupérer des éléments de liste avec un appel, plutôt que d'utiliser simplement un index.

bonne chance!


0 commentaires

1
votes

Il est difficile de dire grand chose avec plus de détails, mais voici une théorie: lorsque vous ajoutez Imprimer , cela soulève réellement un ioError (c'est possible, comme documenté ), qui est capturé et OS.Path.exists (Story.RecentFiles). GetHistoryFile (index)) est pas exécuté, vous ne comprenez donc pas.

Vous pouvez le tester avec un test comme suit (avant le code que vous citez): xxx

qui créera un fichier ioerror_raisis.txt si le impression surélevé ioerror .

Ceci pourrait expliquer pourquoi ajouter un impression fait exécuter le code.

(Si tel est le cas, alors OS.Path.exists (Story. récemmentFiles.GethistoryFile (index)) devrait évidemment être débogué.)


0 commentaires

1
votes

Vous créez une liste statique d'index valides (avec plage ()) au début de la boucle, mais vous supprimez des fichiers de la liste (removerecentfile) dans la boucle.

Donc, votre problème peut être, que vous démarrez la boucle avec 10 fichiers, supprimé un fichier (par exemple, indice 4) car vous ne pouvez pas y accéder, puis essayer d'accéder au fichier le 10ème fichier (index 9) qui n'est pas là encore parce que vous avez déménagé 5-> 4, 6-> 5, 7-> 6, 8-> 7, 9-> 8


1 commentaires

D'accord, je pense que cela ressemble à des bouillons d'optimisation du compilateur, dans lequel le compilateur ajoutez des passes pour permettre la doublure de tuyauterie de telle sorte que les informations puissent être correctes à différentes étapes de différentes tâches.



0
votes

Je ne sais pas si vous portez votre code à la main, mais vous pouvez toujours essayer l'outil automatisé: http://docs.python.org/2/library/2to3.html


0 commentaires