Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python class decorator and maximum recursion depth exceeded

I try define class decorator. I have problem with __init__ method in decorated class. If __init__ method invokes super the RuntimeError maximum recursion depth exceeded is raised.

Code example:

def decorate(cls):
    class NewClass(cls): pass
    return NewClass

@decorate
class Foo(object):
    def __init__(self, *args, **kwargs):
        super(Foo, self).__init__(*args, **kwargs)

What am I doing wrong?

Thanks, Michał

Edit 1

Thanks to Mike Boers answer I realized that correct question is what should I do to achive that super(Foo, self) point to proper class.

I have also two limitation. I want invoke Foo.__init__ method and I can't change Foo class definition.

Edit 2

I have solved this problem. I modify decorator function body. I don't return new class. Instead of I wrap methods of orginal class.

like image 890
Michał Lula Avatar asked Jan 21 '23 22:01

Michał Lula


1 Answers

You need to override NewClass.__init__ to prevent recursion, because NewClass.__init__ is Foo.__init__ and it keeps calling itself.

def decorate(cls):
    class NewClass(cls):
        def __init__(self):
            pass
    return NewClass

New idea:

How about not subclassing it? Maybe monkey patching is your friend?

def decorate(cls):
    old_do_something = cls.do_something
    def new_do_something(self):
        print "decorated",
        old_do_something(self)

    cls.do_something = new_do_something
    return cls

@decorate
class Foo(object):
    def __init__(self, *args, **kwargs):
        super(Foo, self).__init__(*args, **kwargs)

    def do_something(self):
        print "Foo"

f = Foo()
f.do_something()
like image 108
petraszd Avatar answered Jan 24 '23 12:01

petraszd