Last active
January 10, 2022 11:13
-
-
Save taikedz/47603180e2384a195e8740143a121eb3 to your computer and use it in GitHub Desktop.
Python Decorator Example
This file contains 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
""" | |
A Python decorator is a special function that can be added above a | |
callable definition (function, class, anything that implements the | |
`__call__()` method) | |
When a decorated function is called, it is in fact the decorator | |
itself that is called, and the wrapped callable is then normally | |
called by the implementing handler of the decorator. | |
A Python decorator is comprised of 3 parts: | |
* name | |
* wrapped function receiver | |
* decorator implementation | |
In a simple decorator, the name and the function receiver are one. | |
It supplies a handling function, which should call the wrapped | |
function, then return its result. The naming function must return | |
the handler function. | |
In a parameterised decorator, the name and receiver are separated | |
into two functions. The outermost function names the decorator and | |
takes its parameters. The first inner function is a wrapper to | |
receive the target function. | |
We need to import functools and use its 'wraps' decorator to munge | |
the handler, since it is displaced by 1 level, and can cause | |
oddities when stack traces are raised, making debugging difficult. | |
The inner function returns the handler, and the outer function | |
returns the inner function receiver. | |
""" | |
# --------- Simple decorator | |
def printres(func): # decorator name, wrapped function receiver | |
def handler(*args, **kwargs): # decorator handling function | |
res = func(*args, **kwargs) | |
print("{}: {}".format("Result", res)) | |
return res | |
return handler | |
# --------- Decorator with its own parameters | |
import functools | |
def printmsg(message): # decorator name, decorator parameters | |
def function_receiver(func): # wrapped function receiver | |
@functools.wraps(func) # munge func so that stack traces and call sequences are retained | |
def handler(*args, **kwargs): # decorator handling function | |
res = func(*args, **kwargs) | |
print("{}: {}".format(message, res)) | |
return res | |
return handler | |
return function_receiver | |
# ----------- Usage demo | |
@printres | |
def plus(x, y): | |
return x+y | |
@printmsg("minus") | |
def minus(x, y): | |
return x-y | |
z1 = plus(2,3) | |
z2 = minus(3,6) | |
print("Final print: {} // {} ".format(z1,z2)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment