Search code examples
pythonnew-operatorsuper

Why doesn't super.__new__ need argument but instance.__new__ needs?


Trying to understand super and __new__

Here goes my code:

class Base(object):
    def __new__(cls,foo):
        if cls is Base:
            if foo == 1:
                #  return Base.__new__(Child) complains not enough arguments
                return Base.__new__(Child,foo)
            if foo == 2:
                # how does this work without giving foo?
                return super(Base,cls).__new__(Child)  
        else:
            return super(Base,cls).__new__(cls,foo)

    def __init__(self,foo):
        pass 
class Child(Base):
    def __init__(self,foo):
        Base.__init__(self,foo)    
a = Base(1)  # returns instance of class Child
b = Base(2)  # returns instance of class Child
c = Base(3)  # returns instance of class Base
d = Child(1)  # returns instance of class Child

Why doesn't super.__new__ need an argument while __new__ needs it?

Python: 2.7.11


Solution

  • super().__new__ is not the same function as Base.__new__. super().__new__ is object.__new__. object.__new__ doesn't require a foo argument, but Base.__new__ does.

    >>> Base.__new__
    <function Base.__new__ at 0x000002243340A730>
    >>> super(Base, Base).__new__
    <built-in method __new__ of type object at 0x00007FF87AD89EC0>
    >>> object.__new__
    <built-in method __new__ of type object at 0x00007FF87AD89EC0>
    

    What may be confusing you is this line:

    return super(Base,cls).__new__(cls, foo)
    

    This calls object.__new__(cls, foo). That's right, it passes a foo argument to object.__new__ even though object.__new__ doesn't need it. This is allowed in python 2, but would crash in python 3. It would be best to remove the foo argument from there.