Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relationship of metaclass's "__call__" and instance's "__init__"?

Say I've got a metaclass and a class using it:

class Meta(type):
    def __call__(cls, *args):
        print "Meta: __call__ with", args

class ProductClass(object):
    __metaclass__ = Meta

    def __init__(self, *args):
        print "ProductClass: __init__ with", args

p = ProductClass(1)

Output as follows:

Meta: __call__ with (1,)

Question:

Why isn't ProductClass.__init__ triggered...just because of Meta.__call__?

UPDATE:

Now, I add __new__ for ProductClass:

class ProductClass(object):
    __metaclass__ = Meta

    def __new__(cls, *args):
        print "ProductClass: __new__ with", args
        return super(ProductClass, cls).__new__(cls, *args)

    def __init__(self, *args):
        print "ProductClass: __init__ with", args

p = ProductClass(1)

Is it Meta.__call__'s responsibility to call ProductClass's __new__ and __init__?

like image 790
Alcott Avatar asked Sep 20 '11 12:09

Alcott


People also ask

What is the concept of a metaclass?

In object-oriented programming, a metaclass is a class whose instances are classes. Just as an ordinary class defines the behavior of certain objects, a metaclass defines the behavior of certain classes and their instances. Not all object-oriented programming languages support metaclasses.

What is __ metaclass __ in Python?

A metaclass in Python is a class of a class that defines how a class behaves. A class is itself an instance of a metaclass. A class in Python defines how the instance of the class will behave. In order to understand metaclasses well, one needs to have prior experience working with Python classes.

How do you use metaclass in Python?

To create your own metaclass in Python you really just want to subclass type . A metaclass is most commonly used as a class-factory. When you create an object by calling the class, Python creates a new class (when it executes the 'class' statement) by calling the metaclass.

What is difference between INIT and new?

The constructor function in python is called __new__ and __init__ is the initializer function. Quoting the python documentation, __new__ is used when you need to control the creation of a new instance while __init__ is used when you need to control the initialization of a new instance.


1 Answers

There is a difference in OOP between extending a method and overriding it, what you just did in your metaclass Meta is called overriding because you defined your __call__ method and you didn't call the parent __call__. to have the behavior that you want you have to extend __call__ method by calling the parent method:

class Meta(type):
    def __call__(cls, *args):
        print "Meta: __call__ with", args
        return super(Meta, cls).__call__(*args)
like image 51
mouad Avatar answered Nov 15 '22 16:11

mouad