如何在Python中创建函数的独立副本?

2 投票
2 回答
830 浏览
提问于 2025-04-18 17:13

在Python中,有没有办法创建一个不关联的函数副本?比如说,如果我有

a = lambda(x): x
b = lambda(x): a(x)+1

我希望b(x)始终返回x+1,无论a(x)是否被修改。目前,如果我这样做

a = lambda(x): x
b = lambda(x): a(x)+1
print a(1.),b(1.)
a = lambda(x): x*0
print a(1.),b(1.)

输出结果是

1. 2.
0. 1.

而不是我想要的

1. 2.
0. 2.

你有什么想法可以实现这个吗?看起来使用deepcopy对函数没有帮助。而且请记住,a(x)是外部创建的,我不能改变它的定义。我也查过这个方法,但没有用。

2 个回答

1

在我能给出满意的答案之前,我可能需要了解更多关于你的限制条件。你为什么不能做类似这样的事情呢:

a = lambda(x): x
c = a
b = lambda(x): c(x)+1

这样无论发生什么,b 都会保持不变。这是因为在 Python 中赋值的方式有点特别。当你写 c = a 时,名字 c 就和 a 指向的对象关联在一起。你可以用 id() 来查看这个对象的 ID,发现它们是一样的;也就是说,ca 指向的是同一个对象。

c = a
id(a)
>>> 4410483968
id(c)
>>> 4410483968

然后,当你用 a = lambda x: x*0 重新定义 a 时,其实你在一行代码里做了两件事。首先,lambda x: x*0 创建了一个新的函数对象,然后赋值让 a 关联到这个新对象。正如你所看到的,a 现在指向了一个不同的对象:

a = lambda x: x*0
id(a)
>>>> 4717817680

但是如果你查看 id(c),它仍然指向旧的对象!

id(c)
>>>> 4410483968

这是因为当我们重新定义 a 时,我们只是创建了一个新对象,并将 a 关联到它。c 依然和旧的对象关联在一起。

所以如果你像问题中那样重新定义 a,你就会得到你想要的输出:

print a(1.),b(1.)
>>>> 0.0,2.0
2

你可以这样定义b

b = lambda x, a=a: a(x)+1

这样一来,a 就成了 b 的一个参数,也就是说它是一个局部变量。你把它的默认值设为当前环境中 a 的值,这样 b 就会保存这个值。你不需要复制 a,只需保留它当前的值,这样如果有新的值被创建,你就能得到你想要的那个值。

不过,这听起来像是发生了不寻常的事情,如果你能告诉我们更多的情况,可能会有更好的解决办法。

撰写回答