在Python 2.7.x中动态生成部分函数

时间:2014-06-02 19:27:20

标签: python embedded closures ipython partial-application

假设我想从以下lambda动态创建IPython shell上的函数:

f = lambda x, ci: np.percentile(x, 100-ci)

ci修复为新值。它将类似于以下内容(create_new_f是我正在寻找的。)

ci = 20
new_f = create_new_f(f, ci=ci)
result = new_f([20,30,50,80])

我尝试使用functools.partial作为:

new_f = functools.partial(f, ci=20)

但是当我在IPython中的嵌入式shell run this时,我得到:

AttributeError: 'functools.partial' object has no attribute '__module__'

有没有替代这样做的方式,也许是使用装饰器?

关于主题的背景:

  • 这是一个提示问题的IPython issue
  • 这是一个主题explaining the problem(并在Python 3.x中修复)。
  • 这是another thread在SO中显示问题(请参阅顶部评论)
  • 有关此问题的更深入分析,请参阅IPython中的this issue

再次,我正在寻找的是替代这样做的方式。

1 个答案:

答案 0 :(得分:4)

嵌入式IPython的解决方案,

您可以使用闭包实现(我相信这可能是您的解决方案):

import numpy as np
def partial_f(ci):
    def fn(x):
        return np.percentile(x, 100-ci)
    return fn
new_f = partial_f(20)
new_f([20,30,50,80])

返回

62.000000000000014

要检查:

functools.partial在我工作的IDE shell中为我工作:

import functools
import numpy as np
f = lambda x, ci: np.percentile(x, 100-ci)
ci = 20
new_f = functools.partial(f, ci=ci)
new_f([20,30,50,80])

返回

62.000000000000014

使用lambdas(这在IPython online shell中有效,我尝试过,但显然对你的情况不起作用):

import numpy as np
pf = lambda ci: lambda x: np.percentile(x, 100-ci)
new_f2 = pf(20)
new_f2([20,30,50,80])

也会返回

62.000000000000014