【问题标题】:Using functools partial with multiple arguments使用带有多个参数的 functools 部分
【发布时间】:2020-03-29 14:31:45
【问题描述】:

假设,我有一个函数

def func(u,v,w,x, alpha = 4, beta = 5):
    print('u ',u)
    print('v ',v)
    print('x ',w)
    print('u ',x)
    print('** kwarqs: alpha ',alpha)
    print('** kwarqs: beta ',beta)
    return u*4 + v*3 + w*2 + x

我现在想通过使用functools.partial 使其成为部分函数。我将u,v,w 变量设置为常量并创建一个函数 $$part=f(x)|_{u,v,w = \text{const}}$$

u = 2
v = 4
w = 5

part = partial(func,u,v,w, alpha = 'Hello 1', beta = 'Hello 2')
print(part(4))

结果是

u  2
v  4
w  5
x  4   # This is the remaining free variable
** kwarqs: alpha  Hello 1
** kwarqs: beta  Hello 2
34

如何创建函数

f(u) #or f(v),f(w)
f(v,x) #or all other variable combinations
f(v,alpha) # a combination of args and kwargs

最好的问候


也欢迎变通方法。

【问题讨论】:

  • 基本上你想重载函数?
  • @schwobaseggl - 谢谢,我想知道过去 8 年是否发生了一些变化
  • @albusSimba 第三个想要的函数似乎是重载。部分函数是否也被认为是重载函数?
  • 不,它没有。无论您的偏函数采用什么参数,都必须是 kwargs 或传递给偏函数的最后一个位置参数。

标签: python partial functools


【解决方案1】:

我可以推荐您使用lambda吗?

f1 = lambda u : func(u,v,w,x, alpha = 4, beta = 5) 
f2 = lambda v, x: func(u,v,w,x, alpha = 4, beta = 5) 
f3 = lambda v, alpha: func(u,v,w,x, alpha = alpha, beta = 5)  

用法和你想要的一样:

f1(u) #or f(v),f(w)
f2(v,x) #or all other variable combinations
f3(v,alpha) # a combination of args and kwargs

【讨论】:

  • 我不知道,但这就是你想要的吗?
  • 当您必须为每个案例编写带有重新排序的参数的特定 lambda 函数(或传统函数)时,这是一个有用的抽象吗?
  • 您始终可以像 partial 一样事先修复这些值
  • 是的,partial 有它的魅力,但如果在这种情况下无法使用它,我会认为这是最流畅的解决方案。
【解决方案2】:

有趣的问题。你可以去把你的函数变成一个仅限 kwarg 的函数:

from functools import wraps, partial

def kwarged(func):
    @wraps(func)
    def wrapper(**kwargs):
        return func(**kwargs)
    return wrapper

然后您可以使用它来构建任何部分版本:

>>> func = kwarged(func)

>>> f_u = partial(func, v=5, w=2, x=4)
>>> f_u(u=7)
u  7
v  5
w  2
x  4
** kwarqs: alpha  4
** kwarqs: beta  5
51

>>> f_vx = partial(func, u=5, w=2) 
>>> f_vx(v=3, x=6)
u  5
v  3
w  2
x  6
** kwarqs: alpha  4
** kwarqs: beta  5
39
>>> f_vx(v=3, x=6, alpha=9)
u  5
v  3
w  2
x  6
** kwarqs: alpha  9
** kwarqs: beta  5
39

即使所有参数都是带有默认值的 kwargs,您仍然必须传递所有未在部分中设置的原始位置参数:

>>> f_vx(v=3, alpha=9)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 10, in wrapper
TypeError: func() missing 1 required positional argument: 'x'

【讨论】:

    猜你喜欢
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-14
    • 2018-04-23
    相关资源
    最近更新 更多