您对此的直觉是正确的,还有一种更好的方法可以做到这一点:monads。
什么是单子?
Monads(用维基百科来解释)是将操作链接在一起的一种方式,同时隐藏了链接机制。在您的情况下,链接机制是嵌套if
的。隐藏它,您的代码会闻起来更好。
有几个monad可以做到这一点(“也许”和“任何一个”),对您来说很幸运,它们是一个非常漂亮的python monad库的一部分!
他们可以为您的代码做什么
这是一个使用“ Either” monad(链接的库中的“ Failable”)的示例,其中函数可以根据发生的情况返回成功或失败:
import os
class DoSomething(object):
def remove_file(self, filename):
try:
os.remove(filename)
return Success(None)
except OSError:
return Failure("There was an OS Error.")
@do(Failable)
def process_file(self, filename):
do_something()
yield remove_file(filename)
do_something_else()
mreturn(Success("All ok."))
现在,这看起来可能与您现在所拥有的并没有太大不同,但是请考虑一下,如果您进行更多可能导致失败的操作,情况将会如何:
def action_that_might_fail_and_returns_something(self):
# get some random value between 0 and 1 here
if value < 0.5:
return Success(value)
else:
return Failure("Bad value! Bad! Go to your room!")
@do(Failable)
def process_file(self, filename):
do_something()
yield remove_file(filename)
yield action_that_might_fail(somearg)
yield another_action_that_might_fail(someotherarg)
some_val = yield action_that_might_fail_and_returns_something()
yield something_that_used_the_return_value(some_val)
do_something_else()
mreturn(Success("All ok."))
在函数的每个yield
s处process_file
,如果函数调用返回Failure,则process_file
函数将退出,此时从失败的函数返回Failure值,而不是继续执行其余操作并返回Success("All ok.")
现在,想象一下使用嵌套if
s 进行上述操作!(您将如何处理返回值!?)
结论
Monads很好:)
笔记:
我不是Python程序员-我在一个忍者脚本中使用了链接到上面的monad库,以实现某些项目自动化。不过,我认为,通常首选的惯用方法是使用异常。
IIRC在链接的页面上的lib脚本中有一个错字,尽管我忘记了它是ATM。如果我记得的话,我会更新的。我将我的版本与页面的版本进行了比较,发现:def failable_monad_examle():
-> def failable_monad_example():
- 缺少p
in example
。
为了获得Failable装饰函数(例如process_file
)的结果,您必须在中捕获结果,variable
然后执行a variable.value
来获取结果。