Created
November 16, 2021 15:07
-
-
Save udhos/89e0d95edcbbcc0521ebbce20819b75d to your computer and use it in GitHub Desktop.
decorator.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| # | |
| # https://realpython.com/primer-on-python-decorators/ | |
| import functools | |
| import math | |
| # a decorator: | |
| # - takes a function f1 as argument | |
| # - returns a new function f2 | |
| # - when f2 is called it will run extra code in addition to calling f1 | |
| def func_decorator(f): | |
| @functools.wraps(f) # preserves metadata __name__ from original function f into the returned function | |
| def wrapper(x): | |
| # modify both: | |
| # the function argument: x-1 | |
| # the function result: 2*f | |
| return 2*f(x-1) | |
| return wrapper | |
| # will be decorated manually | |
| def func_original(x): | |
| return x+1 | |
| # decorated automatically: | |
| # @func_decorator is just an easier way of saying func_original_decorated = func_decorator(func_original_decorated) | |
| @func_decorator | |
| def func_original_decorated(x): | |
| return x+1 | |
| def main(): | |
| global func_original | |
| # calling decorated func manually | |
| print('func_original(10):', func_original(10)) | |
| func_decorada = func_decorator(func_original) | |
| print('func_decorada(10):', func_decorada(10)) | |
| # decorating manually | |
| print('decorating func_original manually:') | |
| func_original = func_decorada | |
| print('func_original.__name__:',func_original.__name__) | |
| print('func_original(10):', func_original(10)) | |
| # func_original_decorated was decorated automatically with @func_decorator | |
| print('func_original_decorated.__name__:',func_original_decorated.__name__) | |
| print('func_original_decorated(10):', func_original_decorated(10)) | |
| # apply a decorator to a standard library function | |
| print('------') | |
| math.factorial = debug(math.factorial) | |
| print('math.factorial(5):',math.factorial(5)) | |
| def debug(func): | |
| """Print the function signature and return value""" | |
| @functools.wraps(func) | |
| def wrapper_debug(*args, **kwargs): | |
| args_repr = [repr(a) for a in args] # 1 | |
| kwargs_repr = [f"{k}={v!r}" for k, v in kwargs.items()] # 2 | |
| signature = ", ".join(args_repr + kwargs_repr) # 3 | |
| print(f"Calling {func.__name__}({signature})") | |
| value = func(*args, **kwargs) | |
| print(f"{func.__name__!r} returned {value!r}") # 4 | |
| return value | |
| return wrapper_debug | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment