如果将 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。
我有脚本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。