Reputation: 1998
Certain objects are immutable in Python, meaning you can't change them. To get around this, I'm thinking about implementing a solution where I provide a memory location instead of a variables.
Here's an example of the undesirable behavior.
Example of undesirable behavior
x = y = lambda x: x
x(1)
# 1 out
y(1)
# 1 out
y = lambda x: 2*x
y(1)
# 2 out
x(1)
# 1 out
Example of behavior that I'd like to have.
CACHE = {"f": lambda x:x}
class Foo:
def __init__(self, func):
self.func = func
def __call__(self, x):
return self.func['f'](x)
foo = foo2 = Foo(CACHE)
foo(1)
# output 1
foo2(1)
# output 1
CACHE['f'] = lambda x: 2*x
foo(1)
# output 2
foo(2)
# output 2 <-- now it's 2
Is there a solution to this that is less of a cludge?
Upvotes: 0
Views: 52
Reputation: 1086
What you are actually trying to achieve is to have some function pointer which is common to all the objects whose definition you can modify on the fly..
Add a class variable which holds the function and call it from the Call method
In [6]:
...:
...: class Foo:
...: func = None
...: def __call__(self, x):
...: return Foo.func(x)
...:
In [7]: Foo.func=lambda x:x*2
In [8]: f=f1=Foo()
In [9]: f(1)
Out[9]: 2
In [10]: f1(2)
Out[10]: 4
In [11]: Foo.func=lambda x:x
In [12]: f(1)
Out[12]: 1
In [13]: f1(2)
Out[13]: 2
Infact python allows you overwrite function definitions on the fly like this. But i wouldnt prefer to do that:
In [19]: class A:
...: def __call__(self, x):
...: return self.func(x)
...: def func(self, x):
...: return x
...:
In [20]:
In [20]: a=A()
In [21]: a(1)
Out[21]: 1
In [22]: A.func = lambda x:x*2
In [24]: A.func = lambda self, x:x*2
In [25]:
In [25]: a(2)
Out[25]: 4
Upvotes: 1