Why won’t dynamically adding a `__call__` method to an instance work?

Double-underscore methods are always looked up on the class, never the instance. See Special method lookup for new-style classes:

For new-style classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.

That’s because the type might need to support the same operation (in which case the special method is looked up on the metatype).

For example, classes are callable (that’s how you produce an instance), but if Python looked up the __call__ method on the actual object, then you could never do so on classes that implement __call__ for their instances. ClassObject() would become ClassObject.__call__() which would fail because the self parameter is not passed in to the unbound method. So instead type(ClassObject).__call__(ClassObject) is used, and calling instance() translates to type(instance).__call__(instance).

To work around this, you could add a __call__ method to the class which checks for a __call__ attribute on the class, and if there, calls it.

Leave a Comment