Shailendra
Shailendra

Reputation: 548

__new__ is not getting called in object creation

case 1:

class Person:
    def __new__(cls, *args, **kwargs):
        print "called"
        return super(Person, cls).__new__(cls, *args, **kwargs)

p=Person()

case 2:

class Person(object):
    def __new__(cls, *args, **kwargs):
        print "called"
        return super(Person, cls).__new__(cls, *args, **kwargs)

p=Person()

In first case, the __new__() method is not called but in 2nd case it does.

If it doesn't get called, then how is Person object being created?

Upvotes: 1

Views: 68

Answers (2)

devforfu
devforfu

Reputation: 1612

I guess it is something related to new and old style classes in Python2:

Old-style classes don't actually have a __new__ method because for them __init__ is the constructor, so basically if we would have:

class A:

    def __new__(cls):
        print "A.__new__ is called"  # -> this is never called

A()

the body of __new__ will never be executed in this case because it is not the purpose for old-style classes.

In Python3, the behavior is the same, doesn't matter if you explicitly inherit from the object or not:

class Person1:
    def __new__(cls, *args, **kwargs):
        print("called")
        return super(Person1, cls).__new__(cls, *args, **kwargs)


class Person2(object):
    def __new__(cls, *args, **kwargs):
        print("called")
        return super(Person2, cls).__new__(cls, *args, **kwargs)


p1 = Person1()
p2 = Person2()

These should print "called" twice when invoked from 3.x.

Upvotes: 2

intentionally-left-nil
intentionally-left-nil

Reputation: 8274

I was looking for the documentation, and finally found it here: https://staging2.python.org/dev/peps/pep-0253/

The type object has a new slot, tp_new, which can act as a factory for instances of the type. Types are now callable, because the tp_call slot is set in PyType_Type (the metatype); the function looks for the tp_new slot of the type that is being called.

To add onto @devforfu's answer, in the old days, __new__ didn't exist. It was added with the addition of new-style classes.

Upvotes: 1

Related Questions