Was going through Graham Dumpleton's blog post - how you implemented your python decorator is wrong. Simple points that were discussed were -
- Decorators can be functions as well as Classes.
As a class -
class function_wrapper(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def __call__(self, *args, **kwargs):
return self.wrapped(*args, **kwargs)@function_wrapper
def function():
pass
As a function
def function_wrapper(wrapped):
def _wrapper(*args, **kwargs):
return wrapped(*args, **kwargs)
return _wrapper@function_wrapper
def function():
pass
- Use the functools.wraps decorator , it only preserves original functions __name__ and __class__
In functions
import functools
def function_wrapper(wrapped):
@functools.wraps(wrapped)
def _wrapper(*args, **kwargs):
return wrapped(*args, **kwargs)
return _wrapper@function_wrapper
def function():
pass
In classes, use the update_wrapper method-
import functools
class function_wrapper(object):
def __init__(self, wrapped):
self.wrapped = wrapped
functools.update_wrapper(self, wrapped)
def __call__(self, *args, **kwargs):
return self.wrapped(*args, **kwargs) - Python 2.7 preserves Argument specification ( inspect.getargspec ) only in functional decorators, not in class based ones.
- Doesnt preserve function source code for inspection ( inspect.getsource )
- Cannot apply decorators on top of other decorators that are implemented as descriptors.
No comments:
Post a Comment