我有一个方法,按顺序调用其他4个方法来检查特定的条件,并立即返回(不检查以下那些)每当一个返回一些真理。
def check_all_conditions():
x = check_size()
if x:
return x
x = check_color()
if x:
return x
x = check_tone()
if x:
return x
x = check_flavor()
if x:
return x
return None
这似乎是一大堆行李规定。而不是每个2行if语句,我宁愿这样做:
x and return x
但这是无效的Python。我是不是错过了一个简单、优雅的解决方案?顺便说一句,在这种情况下,这四个检查方法可能代价很高,所以我不想多次调用它们。
这种方式有点超出框框,但我认为最终结果是简单的,可读的,而且看起来不错。
基本思想是,当其中一个函数求值为真值时引发异常,并返回结果。下面是它的外观:
def check_conditions():
try:
assertFalsey(
check_size,
check_color,
check_tone,
check_flavor)
except TruthyException as e:
return e.trigger
else:
return None
你需要一个assertFalsey函数,当一个被调用的函数参数的值为真时,它会引发一个异常:
def assertFalsey(*funcs):
for f in funcs:
o = f()
if o:
raise TruthyException(o)
可以对上面的内容进行修改,以便为要计算的函数提供参数。
当然你需要TruthyException本身。这个异常提供了触发异常的对象:
class TruthyException(Exception):
def __init__(self, obj, *args):
super().__init__(*args)
self.trigger = obj
当然,您可以将原始函数转换为更一般的函数:
def get_truthy_condition(*conditions):
try:
assertFalsey(*conditions)
except TruthyException as e:
return e.trigger
else:
return None
result = get_truthy_condition(check_size, check_color, check_tone, check_flavor)
这可能会慢一点,因为您同时使用if语句和处理异常。但是,该异常最多只处理一次,因此对性能的影响应该很小,除非您希望运行该检查并获得成千上万次的True值。
python的方法是使用reduce(有人已经提到过)或itertools(如下所示),但在我看来,简单地使用或操作符的短路可以产生更清晰的代码
from itertools import imap, dropwhile
def check_all_conditions():
conditions = (check_size,\
check_color,\
check_tone,\
check_flavor)
results_gen = dropwhile(lambda x:not x, imap(lambda check:check(), conditions))
try:
return results_gen.next()
except StopIteration:
return None