How to create an independent copy of a function in python?
Question:
Is it possible in python to create an un-linked copy of a function? For example, if I have
a = lambda(x): x
b = lambda(x): a(x)+1
I want b(x)
to always return x+1
, regardless if a(x)
is modified not. Currently, if I do
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.)
the output is
1. 2.
0. 1.
Instead of being
1. 2.
0. 2.
as I would like to. Any idea on how to implement this? It seems that using deepcopy
does not help for functions. Also keep in mind that a(x)
is created externally and I can’t change its definition. I’ve also looked into using this method, but it did not help.
Answers:
You could define b like this:
b = lambda x, a=a: a(x)+1
This makes a
a parameter of b
, and therefore a local variable. You default it to the value of a
in the current environment, so b
will hold onto that value. You don’t need to copy a
, just keep its current value, so that if a new value is created, you have the one you wanted.
That said, this sounds like something unusual happening, and if you tell us more about what’s going on, there’s likely a better answer.
I might need to know a little more about your constraints before I can give a satisfactory answer. Why couldn’t you do something like
a = lambda(x): x
c = a
b = lambda(x): c(x)+1
Then no matter what happens to a
, b
will stay the same. This works because of the somewhat unusual way that assignment works in Python. When you do c = a
, the name c
is linked to the object that a
links to. You can use id()
to look at that object’s id and see that they are the same; c
and a
point to the same object.
c = a
id(a)
>>> 4410483968
id(c)
>>> 4410483968
Then, when you redefine a
with a = lambda x: x*0
, you’re actually doing two things in one line. First, lambda x: x*0
creates a new function object, then the assignment causes the name a
to be linked to the new object. As you can see, a
is now pointing to a different object:
a = lambda x: x*0
id(a)
>>>> 4717817680
But if you look at id(c)
, it still points to the old object!
id(c)
>>>> 4410483968
This is because when we redefined a
, we merely created a new object and linked a
to it. c
remains linked to the old one.
So if you redefine a
as you do in the question, you get the output you want:
print a(1.),b(1.)
>>>> 0.0,2.0
Is it possible in python to create an un-linked copy of a function? For example, if I have
a = lambda(x): x
b = lambda(x): a(x)+1
I want b(x)
to always return x+1
, regardless if a(x)
is modified not. Currently, if I do
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.)
the output is
1. 2.
0. 1.
Instead of being
1. 2.
0. 2.
as I would like to. Any idea on how to implement this? It seems that using deepcopy
does not help for functions. Also keep in mind that a(x)
is created externally and I can’t change its definition. I’ve also looked into using this method, but it did not help.
You could define b like this:
b = lambda x, a=a: a(x)+1
This makes a
a parameter of b
, and therefore a local variable. You default it to the value of a
in the current environment, so b
will hold onto that value. You don’t need to copy a
, just keep its current value, so that if a new value is created, you have the one you wanted.
That said, this sounds like something unusual happening, and if you tell us more about what’s going on, there’s likely a better answer.
I might need to know a little more about your constraints before I can give a satisfactory answer. Why couldn’t you do something like
a = lambda(x): x
c = a
b = lambda(x): c(x)+1
Then no matter what happens to a
, b
will stay the same. This works because of the somewhat unusual way that assignment works in Python. When you do c = a
, the name c
is linked to the object that a
links to. You can use id()
to look at that object’s id and see that they are the same; c
and a
point to the same object.
c = a
id(a)
>>> 4410483968
id(c)
>>> 4410483968
Then, when you redefine a
with a = lambda x: x*0
, you’re actually doing two things in one line. First, lambda x: x*0
creates a new function object, then the assignment causes the name a
to be linked to the new object. As you can see, a
is now pointing to a different object:
a = lambda x: x*0
id(a)
>>>> 4717817680
But if you look at id(c)
, it still points to the old object!
id(c)
>>>> 4410483968
This is because when we redefined a
, we merely created a new object and linked a
to it. c
remains linked to the old one.
So if you redefine a
as you do in the question, you get the output you want:
print a(1.),b(1.)
>>>> 0.0,2.0