Search code examples
pythontypesnew-operatormetaclass

What is the difference between type and type.__new__ in python?


I was writing a metaclass and accidentally did it like this:

class MetaCls(type):
    def __new__(cls, name, bases, dict):
        return type(name, bases, dict)

...instead of like this:

class MetaCls(type):
    def __new__(cls, name, bases, dict):
        return type.__new__(cls, name, bases, dict)

What exactly is the difference between these two metaclasses? And more specifically, what caused the first one to not work properly (some classes weren't called into by the metaclass)?


Solution

  • In the first example you're creating a whole new class:

    >>> class MetaA(type):
    ...     def __new__(cls, name, bases, dct):
    ...         print 'MetaA.__new__'
    ...         return type(name, bases, dct)
    ...     def __init__(cls, name, bases, dct):
    ...         print 'MetaA.__init__'
    ... 
    >>> class A(object):
    ...     __metaclass__ = MetaA
    ... 
    MetaA.__new__
    >>> 
    

    while in the second case you're calling parent's __new__:

    >>> class MetaA(type):
    ...     def __new__(cls, name, bases, dct):
    ...         print 'MetaA.__new__'
    ...         return type.__new__(cls, name, bases, dct)
    ...     def __init__(cls, name, bases, dct):
    ...         print 'MetaA.__init__'
    ... 
    >>> class A(object):
    ...     __metaclass__ = MetaA
    ... 
    MetaA.__new__
    MetaA.__init__
    >>>