Alex
Alex

Reputation: 44305

How to create a decorator function with arguments on python class?

I want to create a decorator function to operate on a python class, with the ability to pass additional arguments. I want to do that before the class gets instantiated. Here is my approach:

def register(x,a):
    print x,a

@register(5)
class Foo(object):
    pass

with x being the class and a the additional argument. But I get a

TypeError: register() takes exactly 2 arguments (1 given)

What I want is some way to get hold of the class Foo and additional arguments at the time the class is defined, before the class is instantiated.

Upvotes: 4

Views: 339

Answers (1)

BrenBarn
BrenBarn

Reputation: 251355

You need to do it this way:

def makeDeco(a):
    def deco(cls):
        print cls, a
        return cls
    return deco

>>> @makeDeco(3)
... class Foo(object):
...     pass
<class '__main__.Foo'> 3

You can use functools.wraps and so forth to spruce it up, but that is the idea. You need to write a function that returns a decorator. The outer "decorator-making" function takes the a argument, and the inner decorator function takes the class.

The way it works is that when you write @makeDeco(3) it calls makeDeco(3). The return value of makeDeco is what is used as the decorator. That is why you need makeDeco to return the function you want to use as the decorator.

Upvotes: 6

Related Questions