Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does __new__ method need passing cls argument when called its parent's __new__ across super method?

Tags:

python

super

I know when we called parent's method across super method we could ignore the "self" argument in a bound method just as below:

class Foo(object):
    def __init__(self):
        super(Foo, self).__init__() # We needn't pass in the "self" argument
        # ...

But something been different in __new__ method:

class Bar(object):
    def __new__(cls, *args, **kwargs):
        return super(Bar, cls).__new__(cls, *args, **kwargs) # Why need a "cls" argument?
like image 523
NSDont Avatar asked Nov 14 '13 08:11

NSDont


1 Answers

__new__ is not an instance method; it is a static method that is passed the class object (making it not quite a class method either).

From the __new__ documentation:

__new__() is a static method (special-cased so you need not declare it as such) that takes the class of which an instance was requested as its first argument.

As such, even when using super() to look up the next __new__ method in the MRO, you still need to pass in cls explicitly.

Special methods with double-underscores are normally looked up on the type, so on the metaclass of the class (which is type() by default). That wouldn't work for __new__ because you declared it directly on the class itself. As such no descriptor protocol can be applied either (which is what normally turns a function into a bound method, for class and instance methods). Thus the __new__ hook had to be special-cased and is never bound.

like image 195
Martijn Pieters Avatar answered Sep 26 '22 00:09

Martijn Pieters