Cannot Overwrite Implementation For __call__
Solution 1:
When you call an object with ()
, it executes the __call__
method defined on the object's type. So __call__
is defined on the class Foo
, not on your instance foo
. If you reassigned Foo.__call__
, it would work.
Foo.__call__ = lambda _: 'bye'
print(foo()) # prints 'bye'
Solution 2:
Try this:
class Foo(object):
def __init__(self, msg):
self._msg = msg
def __call__(self):
return self._msg
foo = Foo('hello')
print(foo()) # Prints 'hello'
Foo.__call__ = lambda _: 'bye' #Notice the capital F, this is the class not the instance
print(foo()) # Prints 'bye'
The last call should print 'bye' like you expect. When you call an instance's functions, it's actually referring to the class functions (where they are defined)
Solution 3:
Typically, you can do this. Override a single instance's implementation of a given method without affecting the rest.
The problem here is that you're attempting to override a "special" method. The ()
call syntax looks up the __call__
method on the class, not the instance.
The following code shows that you can override a single instance's method implementation, as well as serves as sort of an ugly workaround to your problem:
class Foo(object):
def __init__(self, msg):
self._msg = msg
def __call__(self):
return self.call() # Delegate call to instance
def call(self):
return self._msg
foo = Foo('hello')
other = Foo('hi')
print(foo()) # Prints 'hello'
def new_call(self):
return "bye"
foo.call = new_call.__get__(foo, Foo)
print(foo()) # Prints 'bye'
print(other()) # Prints 'hi' (unaffected by override)
Note: the following also would work as you expect:
foo.call = (lambda _: "bye").__get__(foo, Foo)
But I prefer the explicit definition.
Post a Comment for "Cannot Overwrite Implementation For __call__"