Я пишу программу, которая вытаскивает переменные из шаблона и эффективно находит/заменяет шаблон.
Пример шаблона:
VARIABLES
@username
@password
@secret
###########################################################
My username is @username
Password is @password
Secret is @secret
Программа найдет каждую переменную и спросит один за другим для ввода пользователем, откроет файл, сохранит содержимое и закрывает файл для следующей переменной.
Все работает хорошо, кроме странного. Как только я запустил код, конец моего текстового файла выглядит немного диким. См. Ниже вывод. Как вы можете видеть, он успешно взял переменные и поместил их, однако он добавил "TESTis TESTetis @secret" до конца?
VARIABLES
User
Pass
TEST
###########################################################
My username is User
Password is Pass
Secret is TESTis TESTis TESTetis @secret
Я новичок в Python (на этой неделе), поэтому извините код ниже. Я сделал это по-своему! Это может быть не самым эффективным. Просто пытаюсь увидеть, где добавляется дополнительная.
Код:
##COPY CONTENTS FROM READ ONLY TO NEW FILE
with open("TestTemplate.txt", "rt") as fin:
with open("out.txt", "wt") as fout:
for line in fin:
fout.write(line)
fin.seek(0)
fout.seek(0)
fin.close()
fout.close()
##PULL VARIABLES AND FIND/REPLACE CONTENTS
with open("out.txt", "rt") as fin:
with open("out.txt", "rt") as searchf:
with open("out.txt", "r+") as fout:
for line in fin:
if line.startswith("@"):
trimmedLine = line.rstrip()
## USER ENTRY
entry = input("Please Enter " + trimmedLine + ": ")
for line in searchf:
## ENSURE ONLY VARIABLES AFTER '#' ARE EDITED. KEEPS IT NEAT
if trimmedLine in line:
fout.write(line.replace(trimmedLine,entry))
else:
fout.write(line)
##RESET FOCUS TO THE TOP OF THE FILE READY FOR NEXT ITERATION
searchf.seek(0)
fout.seek(0)
заранее спасибо
Вы открываете один и тот же файл (out.txt) в разных режимах одновременно - разве это не кажется вам злым? Это похоже на то, что 3 человека готовятся в одной кастрюле. Один делает яйца, один бекон, третья карамель: может получиться - не хотел бы попробовать ее.
Чистый код IPO-модели (да, старый, но все еще действительный):
Более короткая версия файлов для чтения:
with open("TestTemplate.txt", "rt") as fin,
open("out.txt", "wt") as fout:
text = fin.read() # read in text from template
fout.write(text) # you could simply use module os and copy() the file ...
# or simply skip copying here and use open("out.txt","w") below
Используя фиксированный текст здесь - вы могли бы получить его, как указано выше:
text = """VARIABLES
@username
@password
@secret
###########################################################
My username is @username
Password is @password
Secret is @secret"""
replaceMe = {} # dictionary to hold the to be replaced parts and its replacement
# go through all lines
for l in text.splitlines():
if l.startswith("@"): # if it starts with @, ask for content top replace it with
replaceMe[l.rstrip()] = input("Please Enter {}:".format(l.rstrip()))
newtext = text
# loop over all keys in dict, replace key in text
for k in replaceMe:
newtext = newtext.replace(k,replaceMe[k])
print(text)
print(newtext)
# save changes - using "w" so you can skip copying the file further up
with open("out.txt","w") as f:
f.write(text)
Выход после замены:
VARIABLES
a
b
c
###########################################################
My username is a
Password is b
Secret is c
Ваши строки замены короче, чем оригинальные владельцы шаблонов, что приводит к оставленным символам после выполнения поиска файла. Вы должны усечь файл перед вызовом seek()
чтобы дополнительный символ в конце можно было обрезать.
##RESET FOCUS TO THE TOP OF THE FILE READY FOR NEXT ITERATION
searchf.seek(0)
fout.truncate()
fout.seek(0)
with open(...):
закрывает файлы для вас, удаляет .close () и ищет (). Также вы можете сократить его доwith open("TestTemplate.txt", "rt") as fin, open("out.txt", "wt") as fout:
вы открываете один и тот же файл в разных режимах одновременно - не кажется ли вам это злом? Это все равно что приготовить в одной кастрюле 3 чел. Разных продуктов: один делает яйца, другой - бекон, третий - карамель: может получиться - не хочется дегустации. открыть файл, прочитать содержимое в списке строк, закрыть файл. Поработайте над своими заменами в списке строк. Откройте файл, выведите его снова. будет намного чище код.