python - 在循环中使用 python 中的柯里化(Currying)函数

标签 python lambda currying

所以这里有一些代码可以简化我一直在做的事情:

vars = {
    'a':'alice',
    'b':'bob',
}
cnames = ['charlie', 'cindy']

commands = []

for c in cnames:
    kwargs = dict(vars)
    kwargs['c'] = c
    print kwargs
    commands.append(lambda:a_function(**kwargs))

print commands

def a_function(a=None, b=None, c=None):
    print a
    print b
    print c

for c in commands:
    print "run for "+ repr(c)
    c()

这是它的输出:

{'a': 'alice', 'c': 'charlie', 'b': 'bob'}
{'a': 'alice', 'c': 'cindy', 'b': 'bob'}
[<function <lambda> at 0x1001e9a28>, <function <lambda> at 0x1001e9e60>]
run for <function <lambda> at 0x1001e9a28>
alice
bob
cindy
run for <function <lambda> at 0x1001e9e60>
alice
bob
cindy

我希望得到 charlie,然后是 cindy,为什么 cindy 被显示了两次?

最佳答案

您遇到了经典的绑定(bind)时间问题,@Mike 的解决方案就是经典的解决方案。一个好的替代方法是编写高阶函数:

def makecall(kwargs):
  def callit():
    return a_function(**kwargs)
  return callit

并在循环中使用 commands.append(makecall(kwargs))。两种解决方案都遵循相同的原则(通过参数的传递强制进行早期绑定(bind)——在我的例子中是一个普通参数,在@Mike 中是命名参数的默认值);选择只是风格或优雅的问题(我,虽然我在 super 简单的情况下容忍 lambda,但只要出现最微妙的复杂情况,我就非常喜欢旧的 def ;-).

关于python - 在循环中使用 python 中的柯里化(Currying)函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3107231/

相关文章:

c++ - 带有 C++ lambda 的部分应用程序?

python - 创建 TF-IDF 矩阵 Python 3.6

python - 如何使用 django/python 从网络服务获取返回值

c++ - 热处理 c++11 lambda,同时捕获此指针并指定调用约定

python - boto3 s3 复制对象错误

java - 在 Java 8 中构建 Map 以进行集成测试的重构方法 - 函数式编程的机会?

ios - 泛型的偏函数应用

python - Fabric python 框架中的多主机、多凭据

python - GDAL:python 中缺少 jp2 驱动程序

java - 如何让 eclipse 在可完成的 future 中报告未报告的异常?