我的全部问题听起来是这样的:如何在不使用局部函数的情况下用参数来组成(组合)多个函数调用。
现在下面的当前代码可以正常工作,但是每次提供任何其他参数时,我都需要调用partial:
from functools import partial
def pipe(data, *funcs):
for func in funcs:
data = func(data)
return data
def mult(data, amount=5, bias=2):
return data*amount + bias
def divide(data, amount, bias=1):
return data/amount + bias
result = pipe(5,
mult,
partial(divide, amount=10)
)
print(result)
# 3.7
但是我想部分地在管道函数中被调用。因此,呼叫应以这种方式开始:
result = pipe(5,
mult,
divide(amount=10)
)
答案 0 :(得分:1)
这是一个可以帮助您的实现。它是在函数上使用的修饰符,以便您可以通过调用函数本身而不是partial
来创建partial(func, ...)
函数:
from functools import partial, wraps
def make_partial(func):
@wraps(func)
def wrapper(*args, **kwargs):
return partial(func, *args, **kwargs)
return wrapper
使用您希望其行为使用的任何功能,像这样装饰它:
@make_partial
def divide(data, amount, bias=1):
return data/amount + bias
现在您可以调用pipe
,正如您描述的那样,调用divide(amount=10)
现在也会返回部分。
result = pipe(5, mult, divide(amount=10))
在partial
中进行pipe
调用将很困难,因为您将需要以某种方式传递所需的函数及其默认参数而不调用它。这种方法试图消除这种情况,并使现有功能保持整洁。
我可以建议的唯一其他方法是传递函数列表,部分args列表和关键字参数字典的列表。您的函数签名为pipe(data, funcs, args, kwargs)
。
def pipe(data, funcs, args, kwargs):
for func, arg_list, kwarg_list in zip(funcs, args, kwargs):
data = partial(func, *arg_list, **kwarg_list)(data)
return data
要调用pipe
,会变得更加复杂:
result = pipe(
5,
[mult, divide],
[[], []],
[{}, {'amount': 10}]
)