循环写入文件只写一次

Writing to a file in a loop only writes once

我有一个 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 的内容即使在 运行 循环中也只会更改一次。 有人可以解释这种行为并提出解决此问题的方法。

虽然您更改了 values.py 的内容并且您希望 a 的值相应地更新,但这并没有发生。 那是因为 python 不会不断地监视加载的模块以在它们被更改时重新加载它们。看看这个答案,它与你的非常相似:

脚本首次启动时,您只执行一次 from test.values import a。执行 values.py,它分配 a 变量。

重写文件不会导致 import 再次执行,因此您永远不会用文件中的新值重新分配 a。即使你 re-executed import 声明,它也不会被更新,因为 Python 记住哪些模块已经被导入并且不会 re-import 它们(见 ).

要继续添加文件中的值,您需要重复 运行 整个脚本,而不仅仅是循环调用 changedata()。或者您可以 changedata() 更新 a 变量而不是使用 new.

你在这里:

我使用了一个额外的变量 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()

为了详细说明 Barmar 的评论,您的问题是您没有在每次循环中更新 a 的值。 a 始终为 10(即使您在覆盖文件后重新导入它仍然是 10,因为正如 Barmar 指出的那样,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(),然后该函数试图用新值覆盖 values.pya 的先前值,a + 10。但是函数 returns 这个新值和行 a = changedata(a)a 的值覆盖为值 a + 10 所以在下一次迭代中, changedata() 是正确的试图覆盖这个新值。 a 的原始值将不再在文件 values.py 中找到,因为它已在第一次迭代中被 a + 10 覆盖。