Странное добавление в конце файла .txt после fout.write () - Python

1

Я пишу программу, которая вытаскивает переменные из шаблона и эффективно находит/заменяет шаблон.

Пример шаблона:

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)

заранее спасибо

  • 0
    with open(...): закрывает файлы для вас, удаляет .close () и ищет (). Также вы можете сократить его до with open("TestTemplate.txt", "rt") as fin, open("out.txt", "wt") as fout: вы открываете один и тот же файл в разных режимах одновременно - не кажется ли вам это злом? Это все равно что приготовить в одной кастрюле 3 чел. Разных продуктов: один делает яйца, другой - бекон, третий - карамель: может получиться - не хочется дегустации. открыть файл, прочитать содержимое в списке строк, закрыть файл. Поработайте над своими заменами в списке строк. Откройте файл, выведите его снова. будет намного чище код.
  • 0
    Очень полезные ответы, Патрик, я ценю ваш вклад. Как я уже сказал, я очень новичок в этом, и всегда будут способы оптимизации кода. Такие маленькие хитрости очень помогут мне в будущем! Благодарю вас
Теги:

2 ответа

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
0

Ваши строки замены короче, чем оригинальные владельцы шаблонов, что приводит к оставленным символам после выполнения поиска файла. Вы должны усечь файл перед вызовом seek() чтобы дополнительный символ в конце можно было обрезать.

##RESET FOCUS TO THE TOP OF THE FILE READY FOR NEXT ITERATION
searchf.seek(0)
fout.truncate()
fout.seek(0)
  • 1
    Отлично спасибо! Это исправило эту проблему.
  • 0
    Рад помочь. Можете ли вы пометить этот ответ как принятый, если сочтете его правильным?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню