我想用IPython运行一个python脚本,并能够判断脚本是否成功(一直运行)还是不成功(引发异常)。
通常可以通过检查命令的返回值来判断命令是否成功,其中约定为0表示成功,其他整数表示错误(表示哪个错误的值)。这是使用python script.py
运行脚本时的行为,但使用ipython script.py
时,IPython会自动捕获错误并且(无用)返回退出代码0。
如何在使用IPython运行脚本时禁用此行为?
顺便说一句,我需要在IPython而不是Python中运行脚本,因为脚本是从IPython笔记本(.ipynb)生成的,并包含一些IPython魔术命令。
这是一个最小的工作示例。
fail.py
#! /usr/bin/env python
mytext = 'Hello World!'
if __name__=="__main__":
print(missing_variable)
使用IPython运行脚本时,异常将打印到stdout,返回值为1,正确表示脚本失败。
~$ python fail.py
Traceback (most recent call last):
File "fail.py", line 4, in <module>
print(missing_variable)
NameError: name 'missing_variable' is not defined
~$ echo $?
1
当使用IPython运行脚本时,会捕获异常并将回溯打印到stdout,然后IPython退出并返回0(这是不可取的,因为脚本没有成功)。
~$ ipython fail.py
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
~/fail.py in <module>()
2 mytext = 'Hello World!'
3 if __name__=="__main__":
----> 4 print(missing_variable)
NameError: name 'missing_variable' is not defined
~$ echo $?
0
答案 0 :(得分:2)
正如@chrisaycock和@vrs所指出的那样,ipython GitHub页面上有一个issue discussing this problem。
此外,问题已得到解决并且修复了merged into the ipython main code base,但是修复程序太新了,无法在任何已发布的ipython版本中使用。在编写本文时,最新发布的ipython版本是v4.0.1,解决方案应该在下一个版本v4.1.0中。
暂时可以通过安装ipython的最新版本来解决这个问题,如下所示:
virtualenv --no-site-packages -p /usr/bin/python2.7 tmp-env
source tmp-env/bin/activate
pip install git+git://github.com/ipython/ipython.git@master
我们可以看到现在修复了不良行为:
(tmp-env)~$ pip freeze
argparse==1.2.1
decorator==4.0.6
ipython==4.1.0.dev0
ipython-genutils==0.1.0
path.py==8.1.2
pexpect==4.0.1
pickleshare==0.5
ptyprocess==0.5
simplegeneric==0.8.1
traitlets==4.0.0
wsgiref==0.1.2
(tmp-env)~$ ipython fail.py
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
~/fail.py in <module>()
2 mytext = 'Hello World!'
3 if __name__=="__main__":
----> 4 print(missing_variable)
NameError: name 'missing_variable' is not defined
(tmp-env)~$ echo $?
1
答案 1 :(得分:1)
您似乎无法在IPython中执行此操作(有关详细信息,请参阅this discussion)。您可以做的是使用try/except
,然后使用sys.exit(code_number)
设置所需的退出代码。您还可以使用traceback
模块以Python解释器的方式打印堆栈跟踪。所以你的代码可能如下所示:
import sys, traceback
mytext = 'Hello World!'
if __name__=="__main__":
try:
print(missing_variable)
except:
traceback.print_exc(file=sys.stdout)
sys.exit(1)
然后运行:
~$ ipython fail.py
理论上应该产生堆栈跟踪以及退出代码1:
~$ echo $?
1