I am trying to decorate an actual class, using this code:
def my_decorator(cls):
def wrap(*args, **kw):
return object.__new__(cls)
return wrap
@my_decorator
class TestClass(object):
def __init__(self):
print "__init__ should run if object.__new__ correctly returns an instance of cls"
test = TestClass() # shouldn't TestClass.__init__() be run here?
I get no errors, but I also don’t see the message from TestClass.__init__().
According to the docs for new-style classes:
Typical implementations create a new instance of the class by invoking the superclass’s
__new__()method usingsuper(currentclass, cls).__new__(cls[, ...])with appropriate arguments and then modifying the newly-created instance as necessary before returning it.If
__new__()returns an instance of cls, then the new instance’s__init__()method will be invoked like__init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to__new__().
Any ideas why __init__ isn’t running?
Also, I have tried to call __new__ like this:
return super(cls.__bases__[0], cls).__new__(cls)
but it would return a TypeError:
TypeError: super.__new__(TestClass): TestClass is not a subtype of super
__init__isn’t running becauseobject.__new__doesn’t know to call it. If you change it tocls.__call__(*args, **kwargs), or better,cls(*args, **kwargs), it should work. Remember that a class is a callable: calling it produces a new instance. Just calling__new__returns an instance but doesn’t go through the initialization. An alternative would be to call__new__and then manually call__init__but this is just replacing the logic that is already embodied in__call__.The documentation that you quote is referring to calling
superfrom within the__new__method of the class. Here, you are calling it from the outside and not in the usual way as I’ve already discussed.