Запись в файл в цикле записывается только один раз

У меня есть файл python values.py с содержимым

a=10

У меня есть еще один файл Python execute.py с содержимым

from test.values import a

def changedata():
    with open("values.py",'r+') as f:
        text = f.read()
        new = a + 10
        text = text.replace(str(a), str(new))
        f.seek(0)
        f.write(text)
        f.truncate()

for i in range(0,4):
    changedata()

Когда я запускаю execute.py, в идеале содержимое value.py должно быть a=40, но это a=20

Я не понимаю, почему python не меняет содержимое value.py на каждой итерации при запуске в цикле. В настоящее время содержимое value.py изменяется только один раз, несмотря на то, что оно запускается в цикле. Может кто-нибудь объяснить это поведение, а также предложить способ исправить это.


person Fuze Test    schedule 21.08.2020    source источник
comment
попробуйте удалить f.seek(0)   -  person EEAH    schedule 21.08.2020
comment
Что такое from test.values import a? когда вы делаетеstr(a) на второй петле? Похоже, что str(a) может быть не тем, что вы ожидаете, поэтому, когда он выполняет замену, он не находит его?   -  person jmunsch    schedule 21.08.2020
comment
Вы не увеличили значение a, поэтому оно всегда равно 10. Это означает, что ваш вызов text.replace() работает только для первого вызова, а не для последующих.   -  person domochevski    schedule 21.08.2020
comment
Вы никогда не обновляете значение a, поэтому оно всегда будет записывать значение + 10.   -  person joshmeranda    schedule 21.08.2020


Ответы (4)


Вы выполняете from test.values import a только один раз, когда скрипт запускается впервые. Это выполняет values.py, который назначает переменную a.

Перезапись файла не приводит к повторному выполнению import, поэтому вы никогда не переназначаете a с новым значением из файла. И даже если вы повторно выполните оператор import, он не будет обновлен, поскольку Python запоминает, какие модули были импортированы, и не импортирует их повторно (см. импорт python несколько раз).

Чтобы продолжать добавлять значение в файл, вам нужно многократно запускать весь скрипт, а не просто вызывать changedata() в цикле. Или вы могли бы changedata() обновить переменную a вместо использования new.

person Barmar    schedule 21.08.2020
comment
Спасибо за подробное объяснение. Действительно полезно. :) - person Fuze Test; 21.08.2020

Хотя вы меняете содержимое values.py и ожидаете, что значение a соответственно обновится, этого не происходит. Это потому, что python не постоянно следит за загруженными модулями, чтобы перезагрузить их в случае их изменения. Проверьте этот ответ, он очень похож на ваш: Как мне перезагрузить модуль после его изменения?

person Mohammad Jafar Mashhadi    schedule 21.08.2020

Чтобы уточнить комментарий Бармара, ваша проблема заключается в том, что вы не обновляете значение a каждый раз в цикле. a всегда равно 10 (и все равно будет 10, даже если вы повторно импортируете его после перезаписи файла, потому что, как заметил Бармар, Python достаточно умен, чтобы не импортировать повторно то, что уже было импортировано). Чтобы обойти это, вам нужно изменить значение, которое вы пытаетесь перезаписать при каждой итерации. Одним из простых способов сделать это было бы передать переменную в функцию следующим образом:

from values import a

def changedata(data):
    with open("values.py",'r+') as f:
        text = f.read()
        new = data + 10
        text = text.replace(str(data), str(new))
        f.seek(0)
        f.write(text)
        f.truncate()
        return new

for i in range(0,4):
    a = changedata(a)

В этом коде a передается как переменная функции changedata(), которая затем пытается перезаписать предыдущее значение a в values.py новым значением a + 10. Но затем функция возвращает это новое значение, а строка a = changedata(a) перезаписывает значение a значением a + 10, поэтому на следующей итерации changedata() правильно пытается перезаписать это новое значение. Исходное значение a больше не будет найдено в файле values.py, так как оно было перезаписано a + 10 в первой итерации.

person thehumaneraser    schedule 21.08.2020

Вот, пожалуйста:

Я использую дополнительную переменную tmp. В вашем коде метод замены всегда ищет 10, чтобы заменить его. Но только в первый раз найдите число 10. Все остальные, умноженные на 10, не существуют в values.txt

from test.values import a

tmp = a

def changedata():
    global tmp
    with open("values.py",'r+') as f:
        text = f.read()
        print(text) 

        new = tmp + 10
        
        text = text.replace(str(tmp), str(new))
        tmp = new
        
        f.seek(0)
        f.write(text)
        f.truncate()

for i in range(0,4):
    changedata()

или без использования глобальной переменной и без импорта a:


def changedata():
    with open("values.py",'r+') as f:
        text = f.read()
        print(text) 

        array = text.split("=")

        tmp = int(array[1])
        new = tmp + 10
        
        text = text.replace(str(tmp), str(new))
        
        f.seek(0)
        f.write(text)
        f.truncate()

for i in range(0,4):
    changedata()
person Manolis P.    schedule 21.08.2020