2013-07-11 66 views
1

所以最近我一直在问Python关于更多专业和pythonic风格的问题,尽管我的问题给出了很好的答案,但我觉得我需要提出一个更广泛的问题。通常,在编写处理副作用(文件写入,字典定义等)而不是返回值的效用函数(对于库等)时,返回状态代码以告诉调用它通过或失败的函数。Python返回代码

在Python,似乎有三种方式来标记此:

使用的-1或0(C等)的返回值,并使用语句如

if my_function(args) < 0: 
    fail condition 
pass condition 

,或者使用一回真值/假

if not my_function(args): 
    fail condition 
pass condition 

,或者使用“回报或‘返回None’使用异常(未知错误退出)

try: 
    my_function(args) 
except ExpectedOrKnownExceptionOrError: 
    fail condition 
pass condition 

哪个最好?最正确的?首选?我理解所有的工作,并且没有太多的技术优势(除了可能的异常处理的开销)。

回答

7

不要返回指示错误的东西。抛出一个异常。绝对不要捕捉异常并将其转换为返回码。

+0

+1,这样做会很... C++。 – 2rs2ts

+0

是的,这是EAFP的方法,在Python中很常见。类似C的方法在这里可能是最糟糕的,但最终,这一切都取决于图书馆的确切目标,以及在常见用法方面更一致。 – Tadeck

+0

好的,这是我的问题。如果我的论点不符合功能要求,我应该只是抛出一个基本的异常?像 如果数据<0: 引发异常('bad input') –

1

当发生异常而未捕获时,Python will exit with an error (non-zero) code for you。如果您正在定义自己的例外类型,则应该使用override sys.excepthook()为您提供所需的退出代码,因为它们默认使用退出代码1

如果由于某种奇怪的原因想要指定退出代码,请使用sys.exit()errno模块获取标准退出代码,以便使用适当的退出代码。您也可以使用traceback模块获取堆栈回溯(根据该答案,它似乎也是正确的错误代码)。就我个人而言,我也不喜欢这种方法。

我推荐的方法是不是发现异常;让它发生。如果你的程序在异常发生后可以继续运行,你应该抓住它并适当地处理它。但是,如果你的程序无法继续,你应该让例外。这对于在其他Python模块中重新使用你的程序特别有用,因为如果你愿意的话,你将能够捕捉到异常。

1

很像其他的一切:这取决于。

例外情况对于将本地例程(或其调用者 - 见下文)无法处理或预期处理的错误或条件的错误或条件“传递给”链条有很好的作用。特别是如果“谁”可以处理它位于调用堆栈的几个层次。我认为这是例外情况的“最佳”使用。

异常的不利之处在于,一旦发生异常,即使问题得到解决,也不会再回到原来的位置。你必须从头开始重新开始例程。

返回值适用于预期不会“意外”失败的例行操作。检查返回值并从那里开始。它们对于本地例行程序可以从中恢复的问题也很有用。例如,如果例程预计在放弃之前尝试了3次,返回通过/失败/真/假可能是合适的。

根据我的经验,期待调用者处理来自其被调用者的返回值和异常都只是乏味。在我看来,在Try/Except块中检查返回值只会造成笨拙的逻辑...至少对于我所做的工作而言。

这并不是说您不能使用异常而不是的返回值。确实有可以提供更简洁的代码的情况。

我的妥协方法是试图限制自己在单个例程中返回值或例外。我尝试限制我的呼叫者需要检查的内容。

当我需要这两个,我尝试限制我的使用异常问题,我的直接调用者无法处理。换句话说,我的直接调用者会期望得到一个真/假/无论返回值,但预计也不会处理异常。例外情况可能由,他们的调用者等来处理。当在同一例程中使用两者时,我试图将我的例外限制为真正的“例外”(即不常见的问题)。

此外,首选的Python成语是使用True/False而不是1/0。除非你用C语言编写,否则你要在你的Linux脚本中返回一个Linux退出代码。