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

时间:2014-08-13 21:51:49

标签: python function lambda copy deep-copy

在python中是否可以创建函数的未链接副本?例如,如果我有

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

我希望b(x)始终return 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)是在外部创建的,我无法更改其定义。我也考虑过使用this method,但没有帮助。

2 个答案:

答案 0 :(得分:2)

您可以像这样定义b:

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

这使a成为b的参数,因此成为局部变量。您在当前环境中将其默认为a,因此b将保留该值。您不需要复制a,只需保留其当前值,这样如果创建了新值,您就拥有了所需的值。

那就是说,这听起来像是不寻常的事情发生了,如果你告诉我们更多关于发生了什么的事情,可能会有更好的答案。

答案 1 :(得分:1)

在我给出满意的答案之前,我可能需要更多地了解您的约束。为什么你不能做像

这样的事情
a = lambda(x): x
c = a
b = lambda(x): c(x)+1

然后,无论a发生什么,b都会保持不变。这是因为赋值在Python中有点不寻常的方式。执行c = a后,名称c会链接到a链接到的对象。您可以使用id()查看该对象的ID并查看它们是否相同; ca指向同一个对象。

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

然后,当您使用a重新定义a = lambda x: x*0时,您实际上在一行中做了两件事。首先,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