1

我想一个接一个地执行许多功能。每个函数都返回 True 或 False。因此,如果一个函数返回 True,我想执行下一个函数。ETC...

所有函数都不需要相同的参数。

现在我有类似的东西:

res=function1()
if res:
   res=function2()
   if res:
      res=function2()

它会持续不断地进行 20 种功能。有一个更好的方法吗 ?

先感谢您...

4

4 回答 4

8

好吧,您可以定义自己的方式来执行此操作,但我会这样做:

my_functions = (
    (my_func1, [2, 5], {'kwarg1': 'val1'}),
    # ...
)

for function, args, kwargs in my_functions:
    if not function(*args, **kwargs):
        break

根据评论编辑。伟大的洞察力!

于 2013-02-26T19:52:41.470 回答
4

我可能会partial用来制作可以循环的零参数函数(而不是带有函数及其参数的某种结构):

functions = [
    functools.partial(func1, arg1a, arg1b),
    functools.partial(func2),
    functools.partial(func3, keyword_a=kwarg3a, keyword_b=kwarg3b)
]

然后,您无需将其放入 alist并对其进行迭代,您只需调用all

retval = all(func() for func in (
    functools.partial(func1, arg1a, arg1b),
    functools.partial(func2),
    functools.partial(func3, keyword_a=kwarg3a, keyword_b=kwarg3b)
))

False只要其中一个函数返回False(或任何 false-y),它将立即返回,或者运行所有函数并True在它们都返回True(或任何 true-y)时返回。正如文档所说,它相当于:

def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True

值得将partialstuple与另一个答案中的 s 进行比较,它们作为伪部分,无论是在它们的定义方式还是在它们的调用方式上:

f1 = functools.partial(func, arg1, arg2, kw1=kwarg1, kw2=kwarg2)
f2 = (func1, (arg1a, arg1b), {'kw1': kwarg1, 'kw2': kwarg2 })

f1()
f2[0](*f2[1], **f2[2])

显然,您可以(并且应该,正如 aemdy 的回答所做的那样)通过元组解包使调用更具可读性,但它仍然永远不会像使用真正的部分那样简单。

于 2013-02-26T20:08:51.203 回答
2

您可以利用and运算符的短路行为:

function1() and function2() and function3() and ...

function2只会在 return 时调用,只会在 if 和 returned时调用,function1依此类推。Truefunction3function1function2True

不过,它不一定非常 Pythonic。

由于您总是分配给res,因此您也可以保持ifs 平坦:

res = function1()

if res:
    res = function2()

if res:
    res = function3()

这可能被认为更具可读性,但它确实浪费了大量的垂直空间。不过,至少你没有嵌套if两打深。

于 2013-02-26T19:52:22.880 回答
1

没有必要变得太复杂:

res = function1()
res = res and function2()
res = res and function3()
...

这看起来有点奇怪,但会做你想做的事,而不必将函数调用自己放入字典列表或其他东西中。这只是写 Cairnarvon 答案的更长的方式:

res = (
   function1() and
   function2() and
   function3() and
   ...
   )
于 2013-02-26T22:23:20.210 回答