4

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.

4
  • If you want to do this, you don't define a decorator that accepts two arguments. You define a function that accepts one argument (your a), and make that function return a decorator that accepts one argument (the class). Commented Mar 22, 2013 at 7:01
  • But when I define the function with one argument, it is the class! Just remove twice the ,a above, and the output is <class '__main__.Foo'>. Commented Mar 22, 2013 at 7:03
  • The solution by @ArtsiomRudzenka worked fine Commented Mar 22, 2013 at 7:06
  • possible duplicate of python decorators with parameters Commented Mar 25, 2013 at 10:30

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

4 Comments

You would need another nested function to use @wraps
@Bren: I think this is what I need. But one question, though. How does python know that the inner function deco is a decorator? Is it just any function inside the outer function?
@Alex: The return value of the expression after the @ is what is used as the decorator. The call makeDeco(3) returns a function, so that function is what is used as the decorator. Note the return deco inside makeDeco.
Yes, right, I was somehow misreading to where the second return statement belongs to...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.