4

我创建了一个函数,它返回一个变量指定的值。喜欢

y = 1.
def f(x):
    return y

我需要这个函数作为函数对象来创建另一个对象

dist = dist.distribution(f, other_variables)

这很好用。但是,如果我想创建几个不同的分布对象(在 y 变化的意义上具有不同的函数 f)喜欢

dist = dist.distribution(f, other_variables)
y = 2.
dist2 = dist.distribution(f, other_variables)

那么所有的分布对象只返回最后一个指定的值 y。IE

dist.f()(1.)
>>>> 2.
dist2.f()(1.)
>>>> 2.

而不是预期的

dist.f()(1.)
>>>> 12.
dist2.f()(1.)
>>>> 2.

问题显然是,函数 f 仅在被调用时才访问变量,而不是最初一次。

有办法解决吗?最后我想要的是:一个只有一个变量的函数(x,虽然在这种情况下它没有做任何事情,但在其他情况下需要它),它返回创建分布时的 y 值。所以原则上我希望在初始化分布时,给定的函数是深度复制的,从某种意义上说,它不再受任何变量变化的影响。这可能吗?

4

1 回答 1

6

不要为此使用全局变量。也不需要“深度复制”该功能;全局根本y不是函数状态的一部分。

改用提供范围值的函数工厂,或使用 afunctools.partial()为函数提供默认参数。

功能工厂:

def produce_f(y):
    def f(x):
        return y
    return f

dist = dist.distribution(produce_f(1.), other_variables)

Nowy是 的作用域值f,每次调用时都produce_f()返回一个 值,并存储为 的单元格变量。fyf

演示:

>>> f1 = produce_f(12.)
>>> f2 = produce_f(42.)
>>> f1('foo')
12.0
>>> f2('foo')
42.0

使用functools.partial()

from functools import partial

def f(y, x):
    return y

dist = dist.distribution(partial(f, 1.), other_variables)

这里partial(f, 1.)产生了一个新的可调用对象,它将在调用f(1., ...)时调用,并附加传入的任何额外参数。

演示:

>>> f1 = partial(f, 12.)
>>> f2 = partial(f, 42.)
>>> f1('foo')
12.0
>>> f2('foo')
42.0
于 2013-04-10T21:22:28.743 回答