Ваша проверка того, что входные данные являются файлами .txt, хороша;это избавляет вас от необходимости беспокоиться о передаче 'rb' или 'wb' на open()
.
Вы говорите, что не хотите выделять N байтов для N-байтового файла, опасаясь, что иногда Nможет быть довольно большим.Лучше ограничить выделение памяти размером самой длинной текстовой строки, а не размером самого большого файла.Давайте разберем вспомогательную функцию.Удалите / замените эти строки:
#Open file correspondent to target filepath.
with open(filepath) as f:
# Read it into memory.
s = f.read()
# Find and replace all occurrances of (find).
s = s.replace(find, replace)
# Write these new changes to the target file path.
with open(filepath, "w") as f:
f.write(s)
# increment search counter by one.
searchCounter += 1
вызовом вспомогательной функции и затем увеличением счетчика:
update(filepath, find, replace)
searchCounter += 1
, а затем определите помощника:
def update(filepath, find, replace, temp_fspec='temp'):
assert temp_fspec != filepath, filepath
with open(filepath) as fin:
with open(temp_fspec) as fout:
for line in fin:
fout.write(line.replace(find, replace))
os.rename(temp_fspec, filepath) # overwrites filepath
Использование fileinput
не имеет значения, так как это объединит строки из многих входов в один выходной поток, и вам необходимо связать каждый выход с его собственным входом.Здесь важна идиома for line in
, и она работает в fileinput
так же, как и в предложенном update()
помощнике.
Подумайте о том, чтобы добавить в temp_fspec необычные символы, чтобы уменьшить вероятность столкновения или, возможно, сделатьэто полный путь в той же файловой системе, но над уязвимым поддеревом, поэтому гарантированно никогда не будет конфликтовать.
Эта версия обычно запускается немного дольше, особенно для длинных файлов с короткими строками.Максимальный объем памяти для этой версии должен быть намного меньше, если максимальный размер файла >> максимальная длина строки.Если речь идет о очень длинных строках, то подход бинарного разбиения будет более уместным, если учитывать случай, когда find
может охватывать границу фрагмента.Нам не нужно обрабатывать этот случай в текущем коде, если мы предполагаем, что find
не содержит '\n'
новых строк.
Мы можем упростить две версии вашей процедуры очистки экрана до одной, сформулировав ее таким образом:
def clear_console():
clear = 'cls' if os.name == 'nt' else 'clear'
subprocess.call(clear, shell=True)
return