What arguments are passed to the __new__ method ?

Steven D'Aprano steve at pearwood.info
Wed Mar 2 06:02:37 EST 2016


On Wed, 2 Mar 2016 08:23 pm, ast wrote:


> An other question:
> 
> What is the very first method launched when an instantiation is done ?
> e.g  obj = MyClass(0, 5, 'xyz')
> 
> is it __call__ (from object or MyClass if overriden) ?

No, not object or MyClass. The *metaclass* __call__ is called.

For most objects, the metaclass is `type`.

The metaclass is the type of the class: classes are objects too, which means
that like all objects, they have a class. That is the metaclass.


*** WARNING ***

Metaclasses are a very advanced technique. You are not expected to
understand this.



> then _call__ launches __new__ and then __init__
> This would be coherent with the language
> 
> or is it __new__ then __init__ as said on courses I read ?

Let us create a metaclass that inherits from `type`:



class Meta(type):
    def __new__(meta, name, bases, namespace):
        print "**Creating new Meta instance"
        print "Metaclass:", meta
        print "New class name:", name
        print "Base classes used:", bases
        print "Namespace used as class dict:", namespace
        return type.__new__(meta, name, bases, namespace)
    def __init__(cls, *args):
        print "**Initialising Meta instance %s" % cls
    def __call__(cls):
        print "**Calling Meta instance %s" % cls
        return super(Meta, cls).__call__()



Now let me use that metaclass to create a new class:

class MyClass(object):
    __metaclass__ = Meta
    def __new__(cls):
        print "^^Creating new instance of %s" % cls
        return super(MyClass, cls).__new__(cls)
    def __init__(self):
        print "^^Initialising MyClass instance %s" % self
    def __call__(self):
        print "^^Calling MyClass instance %s" % self
        return "Hello World!"



which prints:

**Creating new Meta instance
Metaclass: <class '__main__.Meta'>
New class name: MyClass
Base classes used: (<type 'object'>,)
Namespace used as class dict: {'__call__': <function __call__ at
0xb7cfdf7c>, '__module__': '__main__', '__metaclass__':
<class '__main__.Meta'>, '__new__': <function __new__ at
0xb7cfdf0c>, '__init__': <function __init__ at 0xb7cfdf44>}
**Initialising Meta instance <class '__main__.MyClass'>


Now let me create a new MyClass instance:

instance = MyClass()


which prints:

**Calling Meta instance <class '__main__.MyClass'>
^^Creating new instance of <class '__main__.MyClass'>
^^Initialising MyClass instance <__main__.MyClass object at 0xb7cf2bec>


Finally, let me call the instance:

print instance()



which prints:


^^Calling MyClass instance <__main__.MyClass object at 0xb7cf2bec>
Hello World!



-- 
Steven




More information about the Python-list mailing list