How to operate decorator on derived python class?

decorator, inheritance, python, python-2.7, python-decorators

Solution

You are replacing the decorated class with a function, and thus the class definition fails.

Specifically, the `super(Derived, self).__init__()` now passes in a function to `super()`:

>>> super(Derived, object())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be type, not function
>>> type(Derived)
<type 'function'>

Class decorators usually alter the class, add, remove or alter it's attributes, then return the class object again.

You should not replace `Derived` with a new class, because your `Derived.__init__()` refers to itself by name. Replacing that name with another class is going to lead to pain (such as infinite recursion).

An example class decorator that does work:

def my_deco(name):
    # define the decorator function that acts on the actual class definition
    def decorator(cls):

        # do something here with the information
        print name, cls

        setattr(class, name, 'Hello world!')

        # return the original, augmented class
        return cls

    # return the decorator to act on the class definition
    return decorator

Problem

I would like to use a decorator to do something with a derived class (e.g. register the class or something). Here is my code: ``` from functools import wraps class Basic(object): def __init__(self): print "Basic::init" def myDeco(name): # define the decorator function that acts on the actual class definition def __decorator(myclass): # do something here with the information print name, myclass # do the wrapping of the class @wraps(myclass) def __wrapper(*args, **kwargs): return myclass( *args, **kwargs) # return the actual wrapper here return __wrapper # return the decorator to act on the class definition return __decorator @myDeco("test") class Derived(Basic): def __init__(self): super(Derived, self).__init__() print "Derived::init" instance = Derived() ``` which gives the following error: ``` TypeError: must be type, not function ``` when the `super` method in `Derived` is called. I assume the variable `Derived` is no longer a `type`, but the function `__decorator` actually. How do I need to change the decorator (and ONLY the decorator) to fix this problem?

Original source