建议构建这样的函数并不常见,但在这种情况下,我认为最好有一些重复的静态定义,而不是依赖于复杂行为难以验证的动态函数 -
def apply_at_1 (f, *a, **kw):
return lambda x, *a2, **kw2: \
f(x, *a, *a2, **kw, **kw2)
def apply_at_2 (f, *a, **kw):
return lambda x, y, *a2, **kw2: \
f(x, y, *a, *a2, **kw, **kw2)
def apply_at_3 (f, *a, **kw):
return lambda x, y, z, *a2, **kw2: \
f(x, y, z, *a, *a2, **kw, **kw2)
def dummy (a, b, c, d, *more):
print (a, b, c, d, *more)
apply_at_1(dummy, 2, 3, 4)(1, 5, 6, 7, 8)
# 1 2 3 4 5 6 7 8
apply_at_2(dummy, 3, 4, 5)(1, 2, 6, 7, 8)
# 1 2 3 4 5 6 7 8
apply_at_3(dummy, 4, 5, 6)(1, 2, 3, 7, 8)
# 1 2 3 4 5 6 7 8
当然,动态函数允许您在 any 位置应用参数,但如果您需要在位置 4(第 5 个参数)应用参数,也许是时候考虑重构了。在这种情况下,我认为最好设置一个合理的限制,然后约束自己。
其他函数式语言出于打字原因做类似的事情。考虑 Haskell 的 liftA2、liftA3、liftA4 等。或者 Elm 的 List.map、List.map2、List.map3、List.map4、...
有时接吻更容易。
这是支持通配符的partial 版本,__ -
def __ ():
return None;
def partial (f, *a):
def combine (a, b):
if not a:
return b
elif a[0] is __:
return (b[0], *combine(a[1:], b[1:]))
else:
return (a[0], *combine(a[1:], b))
return lambda *b: f(*combine(a,b))
def dummy (a, b, c, d, *more):
print (a, b, c, d, *more)
partial(dummy, 1, __, __, 4)(2, 3, 5, 6, 7, 8)
# 1 2 3 4 5 6 7 8
partial(dummy, __, __, 3, __, __, 6, 7, 8)(1, 2, 4, 5)
# 1 2 3 4 5 6 7 8