如果将 subprocess.Popen 用于 运行 另一个脚本,Python 会打开一个文件两次

Python twice opens a file if uses subprocess.Popen for run another script

我有脚本test1.py(例如)

import test2


def main():
    f = open("File.txt")
    test2.run()

    while True:
        pass

if __name__ == '__main__':
    main()

和test2.py

import subprocess, sys, os

def run():
    # Self run
    subprocess.Popen(['C:\Windows\System32\cmd.exe', '/C', 'start',
                          sys.executable, os.path.abspath(__file__)])

def main():
    while True:
        pass

if __name__ == '__main__':
    main()

问题是第二个脚本的启动重新打开文件"File.txt"。为什么第二个脚本在启动时打开文件?

D:\test>Handle.exe File.txt

Handle v4.0
Copyright (C) 1997-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

python.exe         pid: 9376   type: File           29C: D:\test\File.txt
python.exe         pid: 9792   type: File           29C: D:\test\File.txt

子进程继承一个文件句柄以与 Unix 模型兼容(更多解释参见 PEP 446)。在子流程调用之后,原始脚本和新脚本都应该可以访问该文件;在 Windows 上,这意味着打开了两个单独的文件句柄。

如果你想避免这种情况,一个更好的习惯用法是在分叉之前关闭文件,明确地或使用 with 结构:

with open('File.txt', 'r') as inputfile:
    pass # or do something with inputfile

当您调用 test2 时,您的 test1 程序已经打开了该文件。因此,当您创建子进程时,该子进程会继承所有打开的文件 - 包括 File.txt.

请参阅 subprocess 文档中的 notes on file inheritance