在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,但没有帮助。
答案 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并查看它们是否相同; c
和a
指向同一个对象。
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