运行以下代码片段
import subprocess
with open('test', 'w') as f:
f.write('foon')
subprocess.run(['echo', 'bar'], stdout=f)
我实际上期望创建一个文件test
,其中第一行等于foo
,第二行等于bar
。然而,事实证明是相反的顺序,即文件等于
bar
foo
我想知道上面代码片段的正确python版本如何看起来像首先写foo
然后写bar
。当然,我可以将这两个操作分成两个不同的with
语句,如:
import subprocess
with open('test', 'w') as f:
f.write('foon')
with open('test', 'a') as f:
subprocess.run(['echo', 'bar'], stdout=f)
虽然,这是相当糟糕的,因为文件必须打开/关闭两次,现在。有没有更好的解决办法?
由于文件的隐式缓冲,这很可能发生。
如果在写入foo
之后但在启动子进程之前添加显式的flush()
,它应该像预期的那样工作:
import subprocess
with open('test', 'w') as f:
f.write('foon')
f.flush()
subprocess.run(['echo', 'bar'], stdout=f)
或者,您可以在打开文件时禁用对的缓冲。通常不建议这样做,除非您知道自己在做什么,因为许多I/O模式在没有缓冲的情况下会降级:
import subprocess
with open('test', 'w', buffering=1) as f:
f.write('foon')
subprocess.run(['echo', 'bar'], stdout=f)
从技术上讲,上面的并不是禁用缓冲,而是启用面向行的缓冲。也就是说,每当您写入换行符时,文件将自动刷新(就像您在写入&;foo&;之后所做的那样)。要完全禁用缓冲,您需要以二进制模式写入:
import subprocess
with open('test', 'wb', buffering=0) as f:
f.write(b'foon')
subprocess.run(['echo', 'bar'], stdout=f)