Skip to content Skip to sidebar Skip to footer

Cannot Overwrite Implementation For __call__

Take this as an example: class Foo(object): def __init__(self, msg): self._msg = msg def __call__(self): return self._msg foo = Foo('hello') print(foo()) # Print

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:

classFoo(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 instanceprint(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:

classFoo(object):def__init__(self, msg):
        self._msg = msg
    def__call__(self):
        returnself.call()      # Delegate call to instancedefcall(self):
        returnself._msg

foo = Foo('hello')
other = Foo('hi')

print(foo()) # Prints 'hello'defnew_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__"