我有一个脚本,它循环访问几个文件路径,以便使用子进程执行其他一些python和bash脚本。
我知道这些脚本偶尔会失败,我想捕获异常并停止循环/退出调用脚本。 这似乎应该非常简单 - 但我快要让它工作了。
我已经尝试了许多子进程方法,但我似乎无法从其中任何一个(call
,check_call
,check_output
Popen
)捕获CalledProcessError。
# calling.py
for script in ['w', 'x', 'y']:
try:
subprocess.check_output('ipython {}.py'.format(script).split())
except subprocess.CalledProcessError as e:
print "Caught CalledProcessError"
raise
except Exception as e:
print "Caught some other exception"
raise
现在假设第一个脚本引发异常。我希望它导致调用脚本退出。
# w.py
print "w"
a = {}
a[0] # KeyError
相反,调用脚本不会捕获任何异常,调用脚本将继续循环。
$ ipython calling.py
w
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
/Users/h138124/git/exceptional/w.py in <module>()
1 print "w"
2 a = {}
----> 3 a[0]
KeyError: 0
x
y
我遇到了完全相同的问题并开始调试 subprocess.py。
然后我意识到我从未到达subprocess.run()函数中的断点。
比我想到的,我确实在一段时间前安装了 python35 的 subprocess.run 包。
删除包后,它再次工作。
看起来ipython
不会在异常上返回非零退出代码,这是subprocess.check_output
引发CalledProcessError
所必需的。只需使用python
.
$ cat test.py
1/0
$ python test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
1/0
ZeroDivisionError: integer division or modulo by zero
$ echo $?
1
$ ipython test.py
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
/Users/alexhall/Dropbox/python/sandbox/test.py in <module>()
----> 1 1/0
ZeroDivisionError: integer division or modulo by zero
$ echo $?
0
或者,只需导入脚本或使用execfile
或类似的东西。
,我想做发生在你身上的事情,但我不能,因为我没有使用 try 除了(我在 python 2.7 中)。如果你只是这样做会发生什么?
for script in ['w', 'x', 'y']:
out = subprocess.check_output('ipython {}.py'.format(script).split())
print(out)
据我所知,这个神秘的子过程,如果你想让程序停止,你必须从 try except 结构中解开,因为当退出状态为 1 时subprocess.check_output默认情况下会停止。