while 循环并以追加模式打开文件。为什么顺序很重要?

while loop and opening file in append mode. why does the order matter?

我正在关注 'python crash course',其中一个练习题要求我以追加模式 open/create txt 文件 'guest_book' 并创建一个 while 循环来要求用户输入他们的名字, 同时将他们的名字附加到 'guest_book' txt 中并打印他们已被记录。我写了下面的代码。

filename = 'guest_book'

with open(filename, 'a') as f:
    while True:
        name = input('enter name ')
        f.write(name + '\n')
        print(f"You have been added to the guest book, {name}")

问题:while 循环成功,最终打印也成功,但是当我检查 guest_book txt 时。它不记录输入的名称。有趣的是,通过简单地切换 while 循环和打开 txt 命令的顺序,它似乎可以工作,如下所示:

filename = 'guest_book.txt'   

while True:
    with open(filename, 'a') as f:
        name = input('enter name ')
        f.write(name + '\n')
        print(f"You have been added to the guest book, {name}")

两个代码之间的唯一区别是 while 循环和 "with open" 行的切换顺序。有人可以向我解释为什么这个顺序很重要吗?无论我多么努力,我似乎​​都无法理解这背后的逻辑。谢谢

貌似问题是打开的txt文件没有正常关闭,程序强行结束,关闭代码不是运行之类的。原因:

filename = 'guest_book.txt'   

while True:
  with open(filename, 'a') as f:
    name = input('enter name ')
    f.write(name + '\n')
    print(f"You have been added to the guest book, {name}")

有效是因为您不断地关闭和打开文件。

如果你想关闭文件,我建议添加一个保存功能或退出功能。这将使文件正确关闭并自行保存,有点像这样:

filename = 'guest_book'

with open(filename, 'a') as f:
  while True:
    name = input('enter name ')
    if name == 'exit':
         break
    f.write(name + '\n')
    print(f"You have been added to the guest book, {name}")

简短说明

自从你

while True

循环永远不会结束您对文件的更改实际上永远不会“提交”。

详细解释

我们使用的全部原因

with open(filename, 'a') as f:
    f.write("write something")

而不是

f= open("myfile.txt","w+")
f.write("write something")
f.close() 

是这样我们就不必手动关闭文件访问 - 只有在“f.close()”时才会将更改实际写入本地文件!

在您的代码中,一旦您的“with”块结束,就会在幕后调用 close():

with open(filename, 'a') as f:
    while True:
        name = input('enter name ')
        f.write(name + '\n')
        print(f"You have been added to the guest book, {name}")
# close() would be triggered behind the scenes here
# only after completing ALL statements in your with-block, the changes get saved to the file.
print("We never reach this point...")

由于您的代码永远不会达到那个点,因为您有一个“while true 循环”,因此文件永远不会关闭并且更改永远不会写入文件。

在您的第二个代码示例中,文件在“while true”循环的每次迭代中打开和关闭,因为您的 with 块在循环的一次迭代中开始和结束。这意味着所有更改都会在循环的每次迭代中提交。

编辑:

正如MisterMiyagi指出的那样:

"f.close() 释放文件句柄。它还调用(内部等效于)f.flush() 来提交未完成的更改。主要目的是释放不过,文件句柄。"

因此您可以关闭整个文件(因为 Python 在关闭时自动刷新文件)或者在写入后在 while 循环中调用 f.flush() 以刷新内部缓冲区,但要保留文件句柄打开,以防您之后想继续写入。

所以这里是你的第一个代码(带刷新)的工作改编:

filename = 'guest_book'

with open(filename, 'a') as f:
    while True:
        name = input('enter name ')
        f.write(name + '\n')
        f.flush() # making sure the changes are in the file.
        print(f"You have been added to the guest book, {name}")