Skip to content

Instantly share code, notes, and snippets.

@udhos
Created November 16, 2021 15:07
Show Gist options
  • Select an option

  • Save udhos/89e0d95edcbbcc0521ebbce20819b75d to your computer and use it in GitHub Desktop.

Select an option

Save udhos/89e0d95edcbbcc0521ebbce20819b75d to your computer and use it in GitHub Desktop.
decorator.py
#!/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