Reputation: 44305
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
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