What i wanted to achieve:
- Have a decorator...
- ...which can be used to methods in classes,
- ...which can be ised with and without arguments,
- ...and which has access to the actual instance('self' arg) of method
def foo(function):
print "I'm a decorator"
return function
@foo
def bar(a):
print a
print "BAR"@foo works like that:
bar = foo(bar)
And it can't be simpler - the foo function just must return a function(it can be bar or any other function including lambda expression)
def foo(x,y):
print x,y
print "I'm not a real decorator"
def real_decorator(function):
print "I'm a decorator"
return function
return real_decorator
@foo('baz','qwe')
def bar(x):
print x
print "BAR"
Here we have a little bit more complicated case:
@foo('baz','qwe') means:
bar = foo('baz','qwe')(bar)
So- the foo function must handle 'baz' and 'qwe' and return a function which can handle bar function
But what if you need to handle arguments passed to bar function?
def foo(function):
def real_decorator(x,y,z):
print "We are the decorated x=%s, y=%s, z=%s" % (x,y,z)
function(x,y,z)
return function
return real_decorator
@foo
def bar(x,y,z):
print "BAR"
Again- @foo works like that:
bar = foo(bar) - so foo must return a function which handle the same args as bar function
But- what happens if you want to use foo decorator with or without arguments? Answer is simple- you must check type of the outermost function argument.
What is the answer?
def foo(baz=None):
def decorate(function):
def decorate_inside(self, *args, **kwargs):
real_value = self ** 2 function()
setattr(self, 'foobarbaz', real_value)
return real_value
return decorate_inside
mytype = type(baz)
if mytype == types.MethodType or mytype == types.FunctionType:
return decorate(baz)
else: print baz
return decorate
@foodef bar(x) print x
@foo('a')
def baz(x)
print x
And this is what you want. Of course you can use this decorator on methods inside classess too- and self will be the object instance which can be modified.
0 komentarze:
Prześlij komentarz