使用 Python 的 subprocess.Popen 时的异常处理
Exception handling when using Python's subprocess.Popen
在处理打开的文件时,Python 具有 with
语法,可确保文件在离开块时关闭 - 无论异常等如何。
with open('foo.txt') as f:
foo = f.read()
由于进程也是资源,我想知道:使用 Popen
时是否可能或推荐类似的东西?例如,在 finally
子句中 Popen.kill(); Popen.communicate()
应该是 运行 - 假设我不介意在进程完成之前阻塞?
从Python3.2开始Popen
是上下文管理器。
来自 docs:
Popen objects are supported as context managers via the with statement: on exit, standard file descriptors are closed, and the process is waited for.
这应该可以满足您的需求。
这是来自标准库 subprocess.py
的相关部分
在 Python 3.4:
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
if self.stdout:
self.stdout.close()
if self.stderr:
self.stderr.close()
if self.stdin:
self.stdin.close()
# Wait for the process to terminate, to avoid zombies.
self.wait()
现在您可以在 Python 2.7
from subprocess import Popen
class MyPopen(Popen):
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
if self.stdout:
self.stdout.close()
if self.stderr:
self.stderr.close()
if self.stdin:
self.stdin.close()
# Wait for the process to terminate, to avoid zombies.
self.wait()
if __name__ == '__main__':
with MyPopen(['ls']) as p:
print(p)
您可以向任何 class 添加两个自定义方法以实现与 with
语句的兼容性。
class CustomObject(object):
def __enter__(self):
""" This method execudes when entering block. """
return thing_you_want_to_use
def __exit__(self, type, value, traceback):
""" This method execudes on block exit. """
# Tear things down.
对于 2.7,您还可以使用 @contextlib.contextmanager
:
import contextlib
@contextlib.contextmanager
def manage_process(process):
try:
yield process
finally:
for stream in [process.stdout, process.stdin, process.stderr]:
if stream:
stream.close()
process.wait()
例如:
with manage_process(Popen(['ls'])) as p:
print(p)
在处理打开的文件时,Python 具有 with
语法,可确保文件在离开块时关闭 - 无论异常等如何。
with open('foo.txt') as f:
foo = f.read()
由于进程也是资源,我想知道:使用 Popen
时是否可能或推荐类似的东西?例如,在 finally
子句中 Popen.kill(); Popen.communicate()
应该是 运行 - 假设我不介意在进程完成之前阻塞?
从Python3.2开始Popen
是上下文管理器。
来自 docs:
Popen objects are supported as context managers via the with statement: on exit, standard file descriptors are closed, and the process is waited for.
这应该可以满足您的需求。
这是来自标准库 subprocess.py
的相关部分
在 Python 3.4:
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
if self.stdout:
self.stdout.close()
if self.stderr:
self.stderr.close()
if self.stdin:
self.stdin.close()
# Wait for the process to terminate, to avoid zombies.
self.wait()
现在您可以在 Python 2.7
from subprocess import Popen
class MyPopen(Popen):
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
if self.stdout:
self.stdout.close()
if self.stderr:
self.stderr.close()
if self.stdin:
self.stdin.close()
# Wait for the process to terminate, to avoid zombies.
self.wait()
if __name__ == '__main__':
with MyPopen(['ls']) as p:
print(p)
您可以向任何 class 添加两个自定义方法以实现与 with
语句的兼容性。
class CustomObject(object):
def __enter__(self):
""" This method execudes when entering block. """
return thing_you_want_to_use
def __exit__(self, type, value, traceback):
""" This method execudes on block exit. """
# Tear things down.
对于 2.7,您还可以使用 @contextlib.contextmanager
:
import contextlib
@contextlib.contextmanager
def manage_process(process):
try:
yield process
finally:
for stream in [process.stdout, process.stdin, process.stderr]:
if stream:
stream.close()
process.wait()
例如:
with manage_process(Popen(['ls'])) as p:
print(p)