在某些列表上链接函数调用

Posted

技术标签:

【中文标题】在某些列表上链接函数调用【英文标题】:Chaining functions calls on some list 【发布时间】:2021-10-24 17:23:22 【问题描述】:

假设我有三个函数,它需要一个接一个地处理一个列表。

def f1(lst):
    lst_processed = do_something_of_type1(lst)
    return lst_processed

def f2(lst):
    lst_processed = do_something_of_type2(lst)
    return lst_processed

def f3(lst):
    lst_processed = do_something_of_type3(lst)
    return lst_processed

我想按以下顺序对一些input_list 应用这三个函数:f1,然后是f2,因为f2 需要来自f1 的已处理列表,最后是需要返回的f3 f2 的值。

选项 1:

output_list = f3(f2(f1(input_list)))

选项 2:

   output_list1 = f1(input_list)
   output_list2 = f2(output_list1)
   output_list = f3(output_list2)

其中一个是否比另一个更符合 PEP 8?

【问题讨论】:

你需要三个独立的函数吗?为什么不让一个来完成所有的处理?或者创建一个可以进行方法链接的类。 @It_is_Chris 我确实需要所有三个函数,因为我在其中划分了不同类型的处理。对于这种情况,类可能太复杂了,但当然这可能是一种选择。我只是对选择这两个选项感兴趣。 我也想知道为什么在这种情况下类方法链接比选项 1 更受欢迎? 这真的取决于你的具体用途。如果将在多个 .py 文件中使用某些东西和/或如果您需要以不同的顺序调用函数 f3(f1(input_list)) 或其他一些变体。这样做可能更容易Foo(input_list).f1().f3() 方法在不同的情况下使用。在某些情况下,我将只使用 f1、f2 或 f3 或 f3.f2 或 f2.f1,因此它们的通用用途有点不同,但我的问题更多是关于一旦有人遇到这种特定情况,那么哪个选项是更好。 【参考方案1】:

选项 1 更符合 Python 风格,但取决于您为谁编写代码。 在我看来,选项 2 对于初级开发人员来说更具可读性。 你搜索过 pep8 文档吗?

【讨论】:

【参考方案2】:

我认为实际上没有任何内置功能可以做到这一点(functools 似乎是最有可能找到东西的地方),但编写你在那里找到的东西也相对容易

def chainfunc(funcs, arg):
    ret = arg
    for f in funcs:
        ret = f(arg)
    return ret

output_list = chainfunc([f1, f2, f3], lst)

也就是说,您也可以强制 functools.reduce() 单行执行此类操作:

from functools import reduce

output_list = reduce(lambda a, b: b(a), [f1, f2, f3], lst)

【讨论】:

【参考方案3】:

来自这个答案:Is there a chain calling method in Python?

def f1(i):
    return i + 1


def f2(i):
    return i + 1


def f3(i):
    return i + 1


def f4(i):
    return i + 1


from functools import reduce


def chain(*funcs):
    def chained_call(arg):
        return reduce(lambda r, f: f(r), funcs, arg)

    return chained_call


chained = chain(f1, f2, f3, f4)

print(chained(0))

【讨论】:

【参考方案4】:

我会将选项 2 放在它自己的函数中,然后调用它。另外,我不会称他们为f1f2 等。

【讨论】:

f1、f2 等仅用于演示目的 :)【参考方案5】:

为什么需要 3 个函数?

def f(lst):
   lst_1 = do_something_of_type1(lst)
   lst_2 = do_something_of_type2(lst_1)
   lst_processed = do_something_of_type3(lst_2)
return lst_processed

【讨论】:

我假设功能是 1. 不仅在这种情况下有用,2. 为组织等而拆分。 这是在尝试回答问题吗?如果是这样,请编辑答案以明确它是如何回答问题的。

以上是关于在某些列表上链接函数调用的主要内容,如果未能解决你的问题,请参考以下文章

如何从函数创建 Observable?

在 pyqtgraph 中的多个图上链接自动缩放

为啥我的列表项调用了它不应该调用的函数?

获取以某些字母开头的名称列表[关闭]

等待函数完成,直到回调到来

如何强制调用某些构造函数/函数以使用命名参数?