Python: using sys.exit or SystemExit differences and suggestions
在线阅读一些程序员使用
例子
1 2 3 | ref = osgeo.ogr.Open(reference) if ref is None: raise SystemExit('Unable to open %s' % reference) |
或
1 2 3 4 | ref = osgeo.ogr.Open(reference) if ref is None: print('Unable to open %s' % reference) sys.exit(-1) |
号
1 | sys.exit('Unable to open %s' % reference) |
没有实际的区别,但是示例代码中还有另一个区别——
除提升
底层是
在sysmodule.c中定义了
最后一个exit函数在
至于如何处理
我个人的偏好是至少提出
编辑:它们确实是一样的,所以唯一的区别就是程序背后的逻辑。异常是某种"不需要的"行为,从程序员的角度来看,对函数的调用是否更像是"标准"操作。
根据文件,
虽然不同之处得到了许多答案,但https://mail.python.org/pipermail/python-list/2016-april/707470.html提出了一个有趣的观点:
tl;dr:最好只是提出一个"正常"的例外,并且只在脚本的顶层使用
I m on python 2.7 and Linux , I have a simple code need suggestion if I
I could replace sys.exit(1) with raise SystemExit .==Actual code==
1
2
3
4
5
6
7
8
9
10 def main():
try:
create_logdir()
create_dataset()
unittest.main()
except Exception as e:
logging.exception(e)
sys.exit(EXIT_STATUS_ERROR)
if __name__ == '__main__': main()==Changed Code==
1
2
3
4
5
6
7
8
9
10
11 def main():
try:
create_logdir()
create_dataset()
unittest.main()
except Exception as e:
logging.exception(e)
raise SystemExit
if __name__ == '__main__':
main()号
我个人反对这两种做法。我喜欢的模式是这是:
1
2
3
4
5
6
7
8
9 def main(argv):
try:
...
except Exception as e:
logging.exception(e)
return 1
if __name__ == '__main__':
sys.exit(main(sys.argv))注意,main()恢复为一个正常函数返回。
而且,我们中的大多数人都会避免"例外",只让一个除冒泡外的级别:这样就可以获得堆栈回溯调试。我同意它可以阻止记录异常,并使更糟糕的控制台输出,但我认为这是一个胜利。如果你想的话要记录异常,始终会出现以下情况:
尝试:…除E例外:日志记录。异常(E)提升
将异常背诵到日志中,仍然让它冒泡出来正常情况下。
"例外"模式的问题在于它捕获和兽皮每一个例外,不仅仅是你理解的一组狭隘的特定例外。
最后,我们不希望提出一个纯粹的异常类。在python 3我认为它实际上是被禁止的,所以它是不可移植的不管怎样。但即使在python中,最好还是提供一个异常实例,而不是类:
提升系统出口(1)
All the functions in try block have exception bubbled out using raise
Example for create_logdir() here is the function definition
def create_logdir():
try:
os.makedirs(LOG_DIR)
except OSError as e:
sys.stderr.write("Failed to create log directory...Exiting !!!")
raise
print"log file:" + corrupt_log
return Truedef main():
try:
create_logdir()
except Exception as e:
logging.exception(e)
raise SystemExit(a) In case if create_logdir() fails we will get the below error ,is
this fine or do I need to improve this code.Failed to create log directory...Exiting !!!ERROR:root:[Errno 17] File
exists: '/var/log/dummy'Traceback (most recent call last):
File"corrupt_test.py", line 245, in main
create_logdir()
File"corrupt_test.py", line 53, in create_logdir
os.makedirs(LOG_DIR)
File"/usr/local/lib/python2.7/os.py", line 157, in makedirs
OSError: [Errno 17] File exists: '/var/log/dummy'号
我更喜欢冒泡的方法,也许是用日志或警告信息,如:
logging.exception("创建logdir失败:makedirs(%r):%s"%(Log_dir,e))上升
(也不是说日志消息记录了更多的上下文:上下文非常调试问题时很有用。)
对于非常小的脚本,sys.stderr.write可以,但通常您的函数可能会迁移到到库中以便重用;请考虑stderr不是始终放置消息;而不是读取日志模块根据需要使用error()或wanr()或exception()。还有更多配置输出无需接线的地方的范围它进入你的内部功能。
Can I have just raise , instead of SystemExit or sys.exit(1) . This
looks wrong to medef main():
try:
create_logdir()
except Exception as e
logging.exception(e)
raise号
这就是我自己要做的。
思考:例外情况是否已"处理",即情况是否已处理因为它是预期的而被处理?如果不是,就让例外冒泡出来,这样用户就知道一些不被理解的东西程序已发生。
最后,从内部执行SystemExit或sys.exit()通常是不好的。除最外面的main()函数以外的任何函数。我抵制它即使在那里,如果写得好,也可以经常调用主函数从其他有用的地方,这使它成为一个有效的图书馆功能(已重复使用)。这样的函数不应该单方面中止程序。太粗鲁了!相反,让例外冒泡:也许main()的调用方需要它,并且可以处理它。通过中止而不是"提高",你已经剥夺了呼叫者即使你自己也有机会做一些适当的事情(即"main")不知道足够的上下文来处理异常。
所以我是为了"养活"自己。然后只因为你想记录错误。如果不想记录异常,可以避免完全尝试/排除并使用更简单的代码:让调用者担心关于未处理的异常!