Это похоже на ошибку последовательности. Давайте рассмотрим небольшой фрагмент вашего кода, в частности строки, имеющие отношение к filename
:
filename = "source" + str(n) + ".html"
while os.path.isfile(filename):
filename = "source" + str(n) + ".html"
n = n + 1
file = open(filename, "r")
Вы генерируете следующее имя файла до того, как откроете файл (или действительно, проверяете старое имя файла и затем открываете новое). Это немного сложно увидеть, потому что вы действительно обновляете n
, в то время как filename
содержит предыдущее число, но если мы посмотрим на них в последовательности, то выскочит:
n = 1
filename = "source1.html" # before loop
while os.path.isfile(filename):
filename = "source1.html" # first time inside loop
n = 2
open(filename)
while os.path.isfile(filename): # second time in loop - still source1
filename = "source2.html"
n = 3
open(filename) # We haven't checked if this file exists!
Мы можем исправить это несколькими способами. Один из них - переместить все обновление, n
до filename
, в конец цикла. Другой способ - позволить механизму цикла обновлять n
, что намного проще (реальное исправление заключается в том, что мы используем только одно значение filename
в каждой итерации цикла):
for n in itertools.count(1):
filename = "source{}.html".format(n)
if not os.path.isfile(filename):
break
file = open(filename, "r")
#...
С риском выглядеть неясным, мы также можем функционально выразить шаги (я использую six здесь, чтобы избежать различий между Python 2 и 3; карта Python 2 не закончится):
from six.moves import map
from itertools import count, takewhile
numbers = count(1)
filenames = map('source{}.html'.format, numbers)
existingfiles = takewhile(os.path.isfile, filenames)
for filename in existingfiles:
file = open(filename, "r")
#...
Другие опции включают в себя итерацию только по числам и использование break
, когда isfile
возвращает False
, или просто перехват исключения, когда open
не удается (полностью исключая необходимость в isfile
).