我对Python还很陌生,所以我想弄清楚如何做到这一点并需要一些帮助。
我使用返回代码来验证我的内部函数是否成功返回。例如(来自内部库函数):
result = some_function(arg1,arg2)
if result != OK: return result
或(从主脚本级别):
result = some_function(arg1,arg2)
if result != OK: abort_on_error("Could not complete 'some_function': %s" % messages(result))
我可以将它降低到一行而不会让它变得不可读吗?
编辑:有些人认识到例外可能是更好的选择。我想仅为非常“特殊”的场景捕获保存异常。返回代码有时可能会失败,我认为在这种情况下使用异常通常是不好的做法。
答案 0 :(得分:10)
您是否可以使用例外来表示失败,而不是返回代码?那么你的大多数if result != OK:
陈述都会消失。
答案 1 :(得分:3)
答案 2 :(得分:3)
听起来好像你想要的东西......
if result = some_function(arg1, arg2):
return result
这在Python中是非常有意的。编写if a = b
而不是if a == b
这是一个很常见的拼写错误,并且允许这种情况与流量控制混合。如果有必要,将其分成两行:
x = some_function()
if x:
print "Function returned True"
更实际的例子是......
result = re.match("a", "b")
if result:
print result.groups()
(更准确地说,在这种情况下你应该做if result is not None:
,虽然上面有效)
在您的特定情况下(“验证我的内部函数是否成功返回”),听起来您应该使用异常。如果一切都很好,只需返回任何你想要的东西。如果出现问题,请提出异常。
Python中的异常与许多其他语言不同 - 例如,它们用于内部流控制(例如StopIteration异常)
我认为以下远比使用返回码更多Pythonic:
#!/usr/bin/env python2.6
def some_function(arg1, arg2):
if arg1 + arg2 > 5:
return "some data for you"
else:
raise ValueError("Could not complete, arg1+arg2 was too small")
然后,您可以在一行中调用该函数:
return some_function(3, 2)
这会返回值,或者引发异常,你可以在某个合理的地方处理异常:
def main():
try:
result = some_function(3, 5)
except ValueError, errormsg:
print errormsg
sys.exit(1)
else:
print "Everything is perfect, the result was {0}".format(result)
或者,如果这种情况实际上是一个错误,只需使用一个很好的堆栈跟踪暂停应用程序。
是的,它比一行长得多,但Python背后的想法是简洁,但外观和可读性。
基本上,如果函数不能再继续,则引发异常。处理此异常,无论您可以从问题中恢复,还是向用户显示错误消息。除非您正在编写库,在这种情况下请保留异常以将堆栈运行到调用代码
或者,以诗的形式:
$ python -m this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
最后,可能值得阅读Python的样式指南"PEP 8"。它可能会回答你的一些问题,例如“如果声明是单线的'pythonic'吗?”
通常不鼓励使用复合语句(同一行上的多个语句)。
是:
if foo == 'blah': do_blah_thing() do_one() do_two() do_three()
而不是:
if foo == 'blah': do_blah_thing() do_one(); do_two(); do_three()
答案 3 :(得分:1)
如果您坚持使用不使用例外,那么我会写两行(这里一行太长):
res = some_function(arg1, arg2)
return res if res != OK else ...
顺便说一句,我建议你提出函数返回的一些 static 类型的值(尽管在Python中进行动态类型化)。例如,您可以返回“int
或None
”。您可以将这样的描述放入docstring。
如果您有int
个结果值和int
错误代码,您可以通过引入错误类来区分它们:
class ErrorCode(int): pass
然后检查isinstance
的结果ErrorCode
。
答案 4 :(得分:-1)
除了例外,使用装饰器是解决此问题的好方法:
# Create a function that creates a decorator given a value to fail on...
def fail_unless(ok_val):
def _fail_unless(f):
def g(*args, **kwargs):
val = f(*args, **kwargs)
if val != ok_val:
print 'CALLING abort_on_error...'
else:
return val
return g
return _fail_unless
# Now you can use the decorator on any function you'd like to fail
@fail_unless('OK')
def no_negatives(n):
if n < 0:
return 'UH OH!'
else:
return 'OK'
在实践中:
>>> no_negatives(9)
'OK'
>>> no_negatives(0)
'OK'
>>> no_negatives(-1)
'CALLING abort_on_error...'
我知道定义fail_unless
的语法有点棘手,如果你不习惯装饰器和函数闭包但fail_unless()
的应用程序是不是很好吗?< / p>