Sheena
Sheena

Reputation: 16212

Python sometimes does not pass class instance as first parameter - understanding __new__

I have a class with a function like this:

def foo(self):
    do_stuff()

And I call it like this:

instance.foo()

and I get this error:

TypeError: foo() takes exactly 1 argument (0 given)

but this works fine:

instance.foo(instance)

Can anyone explain why this could be happening? It's weirding me out a little

If you need more info please feel free to ask

EDIT here's an approximation of the actual code...

def __new__(self):
    blah blah
    MyClass.__init__(self,blah)
    self.foo(self)     #<------------------------error here

I suspect I am misunderstanding how __new__ works... I'm doing some reading now

Upvotes: 1

Views: 173

Answers (2)

Sheena
Sheena

Reputation: 16212

class MyClass  
    def __new__(cls):
        blah
        o = object.__new__(cls)
        o.foo()
        return o

__new__ needs to return an instance. It gets MyClass as an argument, not an instance of MyClass.

To instantiate MyClass in __new__, object.__new__ is employed. This is to prevent infinite recursion

__init__ is called automatically on the returned value of __new__ so long as this value is of type MyClass. This can be prevented by playing with the metaclass

Upvotes: 0

Diego Duclos
Diego Duclos

Reputation: 31

The issue here is that the new function does not accept self as an argument, seeing as you're creating a new object in it. The first argument is in fact the class, usually shortened as cls.

Source

Corrected sample:

def __new__(cls):
    blah blah
    obj = MyClass.__new__(MyClass)
    obj.foo()
    return obj

This will create an instance of MyClass instead of cls. If MyClass is a subclass of cls, then it's init method will also automaticly be called (see linked reference)

Upvotes: 3

Related Questions