2
class Meta(type):
    def __call__(cls, *args, **kwargs):
        print 'Meta.__call__ called.'
        return super(Meta, cls).__call__(*args, **kwargs)


class MetaInstance(object):
    __metaclass__ = Meta

# Instantiate class.
MetaInstance()  # Meta.__call__ called.


class StandardClass(object):
    @classmethod
    def __call__(cls, *args, **kwargs):
        print 'StandardClass.__call__ called.'
        return super(StandardClass, cls).__call__(*args, **kwargs)

# Instantiate class.
StandardClass()  # StandardClass.__call__ is not called!

Why metaclass's __call__ method called on class, but native class's __call__ not, when i instantiate a class?

Pavel Patrin
  • 1,630
  • 1
  • 19
  • 33

2 Answers2

3

When you create a class instance, the metaclass's (whose instance the class is) __call__ is called.

# Instantiate class.
StandardClass()  # StandardClass.__call__ is not called!

When you create a class instance and then "call" the instance, then the class's __call__ is called. I don't think decorating __call__ with classmethod will work though.

This will call your metaclass's and class's __call__s:

StandardClass()()
warvariuc
  • 57,116
  • 41
  • 173
  • 227
  • I may be wrong, but : Does "_the metaclass's `__call__`_" from your first sentence mean "_the `__call__` method defined in the metaclass's scope and the metaclass's instances (the class objects) will have_" (`someclass.__call__`)? Isn't it more "_the class object's (`MetaInstance` and `StandardClass` here) `__call__` method_" then? Isn't the default metaclass's `__call__` method just the `type.__call__` method (aka `type()` function if we misuse language)? – vmonteco Jan 25 '17 at 15:26
  • @vmonteco "the `__call__` method defined in the metaclass's scope and the metaclass's instances (the class objects) will have" < metaclass's instances (the class objects) will NOT have this `__call__` -- it's not inherited by classes from their metaclass. – warvariuc Jan 25 '17 at 17:20
  • I don't understand the other things you mentioned – warvariuc Jan 25 '17 at 17:21
  • Yet, if I define a custom metaclass class with a `__call__` method that prints `"bar"`, if I build my class `foo` with this metaclass, and call `foo.__call__`, `"bar"` will be displayed. – vmonteco Jan 25 '17 at 17:35
  • I think "the `__call__` method defined in the metaclass's scope and the metaclass's instances (the class objects) will have" is not technically correct, because "metaclass's instances (the class objects)" don't have this method. If you override it -- it is not called. Magic methods are always [called on the class, not instance](http://stackoverflow.com/a/34491119/248296). – warvariuc Jan 25 '17 at 18:41
2

Because magic methods are looked up on the class. In other words, when you write a __call__ method on a class, it defines what happens when you call an instance of that class, not what happens when you call the class itself. A class is an instance of its metaclass, so defining __call__ on the metaclass defines what happens when you call the class.

You can already see in your example that you're not doing the same thing in the two cases. For the metaclass example, you defined two things, a metaclass and a "meta-instance" (i.e., a regular class), and you called the second one. For the second example, you only defined one thing (a class). To be parallel to the first example, you would need to create an instance of StandardClass and then call that, in which case StandardClass.__call__ will be called.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384