How to decorate a class?

decorator, python

Solution

I would second the notion that you may wish to consider a subclass instead of the approach you've outlined. However, not knowing your specific scenario, YMMV :-)

What you're thinking of is a metaclass. The `__new__` function in a metaclass is passed the full proposed definition of the class, which it can then rewrite before the class is created. You can, at that time, sub out the constructor for a new one.

Example:

def substitute_init(self, id, *args, **kwargs):
    pass

class FooMeta(type):

    def __new__(cls, name, bases, attrs):
        attrs['__init__'] = substitute_init
        return super(FooMeta, cls).__new__(cls, name, bases, attrs)

class Foo(object):

    __metaclass__ = FooMeta

    def __init__(self, value1):
        pass

Replacing the constructor is perhaps a bit dramatic, but the language does provide support for this kind of deep introspection and dynamic modification.

Problem

How do I create a decorator that applies to classes? Specifically, I want to use a decorator `addID` to add a member `__id` to a class, and change the constructor `__init__` to take an `id` argument for that member. ``` def getId(self): return self.__id classdecorator addID(cls): def __init__(self, id, *args, **kws): self.__id = id self.getId = getId cls.__init__(self, *args, **kws) @addID class Foo: def __init__(self, value1): self.value1 = value1 ``` The above should be equivalent to: ``` class Foo: def __init__(self, id, value1): self.__id = id self.value1 = value1 def getId(self): return self.__id ```

Original source

Related problems