Проблемы с проверкой существования файла Python - если я не добавляю оператор печати

Я переношу программу из Python2 (не знаю точной версии) на Python3.3 и обновляю несколько вещей, но этот цикл, который проверяет существование набора недавно доступных путей к файлам против реальных файлов аварии.

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

Доступ к одному файлу отлично работает, поэтому это связано с циклом. Если я пройду через цикл с помощью отладчика, код будет работать нормально, но если я просто запустил приложение, он выйдет из строя, когда ошибка "python.exe перестала отвечать".

Самая странная часть, однако, должна состоять в том, что когда я добавляю оператор печати перед os.path.exists, он работает с обычным прохождением:

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

Что с этим связано? Я предполагаю, что он имеет какое-то отношение к скорости цикла и времени доступа к файлу или что-то, потому что медленный шаг позволяет ему выполнять штраф, но я честно не знаю, в чем проблема.

Ответ 1

С подробностями трудно сказать, но вот теория: когда вы добавляете print, это фактически вызывает IOError (это возможно, поскольку документировано), который пойман, а os.path.exists(story.recentFiles.GetHistoryFile(index)) не выполняется, поэтому ваша программа не зависает.

Вы можете протестировать это с помощью теста, подобного следующему (до кода, который вы указываете):

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

который создаст файл ioerror_raised.txt, если print поднял IOError.

Это может объяснить, почему добавление print делает запуск кода.

(Если это так, то os.path.exists(story.recentFiles.GetHistoryFile(index)) следует явно отлаживать.)

Ответ 2

В начале цикла создается статический список допустимых индексов (с диапазоном()), но вы удаляете файлы из списка (RemoveRecentFile) внутри цикла.

Таким образом, ваша проблема может заключаться в том, что вы запускаете цикл с 10 файлами, удаляете один файл (например, индекс 4), потому что вы не можете получить к нему доступ, а затем попытайтесь получить доступ к файлу 10-го файла (индекс 9), который не является там, потому что вы переместили 5 > 4, 6- > 5, 7- > 6, 8- > 7, 9- > 8

Ответ 3

Вы взаимодействуете с некорректно написанным кодом C/С#/С++, поэтому трудно указать, где ошибка.

То, что оно плохо написано, очевидно из того, как API заставляет вас получать элементы списка с помощью вызова, а не просто использовать индекс.

Удачи!

Ответ 4

Я не уверен, что вы портируете свой код вручную, но вы всегда можете попробовать автоматизированный инструмент: http://docs.python.org/2/library/2to3.html