Jacky Wang
Jacky Wang

Reputation: 3490

A confusion on type.__init__ in Python 2

Take a look at the following example

class Base(type):
    def __init__(cls, name, bases, dict_):
        print 'Base.__init__() with cls %s, name %s...' % (cls, name, )
        type.__init__(cls, name, bases, dict_)

M = Base('M', (object,), {})

class D1(Base):
    pass

class D2(M):
    pass

The output is

Base.__init__() with cls <class '__main__.M'>, name M...
Base.__init__() with cls <class '__main__.D2'>, name D2...

I feel so puzzled about the result,

  1. Why Base.__init__ be invoked for D2, even we have not creat an instance of D2?
  2. Since Base.__init__ be invoked for D2, why D1 not?

Upvotes: 0

Views: 108

Answers (1)

Moses Koledoye
Moses Koledoye

Reputation: 78556

Base.__init__ is called the first time when you do:

M = Base('M', (object,), {})

You're creating an instance of Base, so its __init__ method gets called, nothing surprising.

It is called the second time when creating D2 because creating a class calls the __init__ method of the metaclass (yep, class of the class) which is Base; D2 is an instance of Base.

It is not called for D1 since D1 is a subtype/subclass of Base and not an instance of it.

Notice what happens when you make Base the metaclass of D1 instead of its superclass:

class D1(object):
    __metaclass__ = Base
    pass

# Base.__init__() with cls <class 'D1'>, name D1...

Upvotes: 2

Related Questions