例子:
subprocess.call(cmd, stdout=open('status_grid','a'), cwd = folder)
文件 status_grid 是否自动关闭?
不,它不会:
import subprocess
f = open('b','a')
subprocess.call('ls', stdout=f)
print f.closed
输出:
False
现在更好的答案可能来自 unutbu。你没有给你打开的文件一个引用,所以一旦你的子进程完成,它取决于垃圾收集器文件打开多长时间。
一种可以确定的方法是
with open('status_grid', 'a') as my_file:
subprocess.call(cmd, stdout=my_file, cwd = folder)
如果没有明确完成,文件将在垃圾收集时关闭。当文件被垃圾收集时,Python 语言本身没有指定。
在 CPython 中,当不再有对文件对象的引用时,该文件将被垃圾回收。
对于 Python 的其他实现,例如 Jython,垃圾收集的发生可能完全不同:
Jython 具有“真正的”垃圾收集,而 CPython 使用引用计数。这意味着在 Jython 中,用户无需担心处理循环引用,因为可以保证正确收集这些引用。另一方面,Jython 的用户无法保证对象何时会最终确定——这可能会给过度使用 open("foo", 'r').read() 的人带来问题。这两种行为都是可以接受的——而且极不可能改变。
正如 EMS 和 Charles Salvia 所指出的,要确定文件何时关闭,最好不要将其留给垃圾收集器。最好的方法是使用一个with
语句,它保证当 Python 离开时文件将被关闭with-suite
:
with open('status_grid','a') as f:
subprocess.call(cmd, stdout=f, cwd = folder)
不,这不对。您可以将调用包装在 with
语句中以确保文件自动关闭:
with open('status_grid','a') as myfile:
subprocess.call(cmd, stdout=myfile, cwd = folder)
注意:在当前基于引用计数的 CPython 实现中,当引用计数达到 0 时,文件将被关闭,这将在您发布的代码中立即发生。然而,这只是 CPython 的一个实现细节。其他实现可能会无限期地打开文件。使用该with
语句来确保您已经编写了可移植代码。