简体   繁体   中英

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.

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()

Remember that a decorator is simply syntactic sugar for:

>>> Foo = decorate(Foo)

So in this case the name Foo actually refers to the NewClass class. Within the Foo.__init__ method you are in fact asking for the super __init__ of NewClass , which is Foo.__init__ (which is what is currently running).

Thus, your Foo.__init__ keeps receiving its own __init__ to call, and you end up in an infinite recursion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM