Most examples of creating decorators in python, show a function returning an inline function. If you wanted to initialize the decorator in some way, you'd have to write a function, initializing a function, returning a function.
When you manage to wrap your head around it, it's not even that complicated, but the combination of three levels of nested functions and scope was confusing to me at first.
I had a eureka moment, when I realized that a decorator could be any callable.
So a class implementing __call__
would suffice.
Again, this probably falls into the personal preference category, but
separating the initializing code into a
__init__ method and the
wrapping code into a __call__ method, made it a lot clearer to me.
An example:
class MyDecorator(object):
""" this decorator prints a custom msg before executing """
def __init__(self, msg):
""" initialize decorator """
self.msg = msg
def __call__(self, func):
""" wrap function with _wrapper function """
def _wrapper(*args, **kwargs):
print self.msg
return func(*args, **kwargs)
return _wrapper
This simple class-based decorator, can now be used as followed:
@MyDecorator("Hello")
def test(name):
print name
The output will be:
>>> test("gumuz")
Hello
gumuz
I hope someone thought this was as insightful as I found it to be. In the next post I will show you how to create a more useful decorator using classes and class-variables.
blog comments powered by Disqus