Last active
May 28, 2021 12:03
-
-
Save PiDroid-B/1e2002e18b33b80a31767cde6d321bbf to your computer and use it in GitHub Desktop.
Python - exemple décorateurs
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
# qui est quoi, identification des différents éléments | |
def deco1(): | |
print("IN deco1") | |
def fonc1(): | |
print("IN fonc1") | |
return "return fonc1" | |
print("OUT deco1") | |
return fonc1 |
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
>>> mon_test = deco1() | |
IN deco1 | |
OUT deco1 | |
>>> mon_test | |
<function deco1.<locals>.fonc1 at 0x7f8e6e5694c0> | |
>>> mon_test.__name__ | |
'fonc1' | |
>>> print(f"mon_test renvoie '{mon_test()}'") | |
IN fonc1 | |
mon_test renvoie 'return fonc1' |
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
# un décorateur qui décore une fonction | |
def deco2(func): | |
print(f"IN deco2, ARG func = {func.__name__}") | |
def fonc2(*args, **kwargs): | |
print(f"IN fonc2 and RUN func {func.__name__} with {args}, {kwargs}") | |
result = func(*args, **kwargs) | |
print(f"OUT fonc2 and return result of {func.__name__} exec") | |
return result | |
print("OUT deco2") | |
return fonc2 |
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
>>> @deco2 | |
... def toto(): | |
... print("toto") | |
... | |
IN deco2, ARG func = toto | |
OUT deco2 | |
# OU | |
>>> def toto(): | |
... print("toto") | |
... | |
>>> toto = deco2(toto) | |
IN deco2, ARG func = toto | |
OUT deco2 | |
>>> toto() | |
IN fonc2 and RUN func toto | |
toto | |
OUT fonc2 and return result of toto exec | |
# De même pour une fonction avec arguement | |
>>> @deco2 | |
... def titi(a,b): | |
... print(f"{a} et {b}") | |
... | |
IN deco2, ARG func = titi | |
OUT deco2 | |
>>> titi("c'est parti", b="mon kiki") | |
IN fonc2 and RUN func titi with ("c'est parti",), {'b': 'mon kiki'} | |
c'est parti et mon kiki | |
OUT fonc2 and return result of titi exec |
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
>>> @deco2 | |
... @deco2 | |
... def pouet(a): | |
... print(a) | |
... | |
IN deco2, ARG func = pouet | |
OUT deco2 | |
IN deco2, ARG func = fonc2 | |
OUT deco2 | |
>>> pouet('dsdf') | |
IN fonc2 and RUN func fonc2 with ('dsdf',), {} | |
IN fonc2 and RUN func pouet with ('dsdf',), {} | |
dsdf | |
OUT fonc2 and return result of pouet exec | |
OUT fonc2 and return result of fonc2 exec |
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
# un décorateur qui inclus un autre décorateur | |
def deco3a(func): | |
print(f"IN deco3a, ARG func = {func.__name__}") | |
def fonc3a(*args, **kwargs): | |
print(f"IN fonc3a and RUN func {func.__name__} with {args}, {kwargs}") | |
result = func(*args, **kwargs) | |
print(f"OUT fonc3a and return result of {func.__name__} exec") | |
return result | |
print("OUT deco3a") | |
return fonc3a | |
def deco3b(func): | |
print(f"IN deco3b, ARG func = {func.__name__}") | |
@deco3a | |
def fonc3b(*args, **kwargs): | |
print(f"IN fonc3b and RUN func {func.__name__} with {args}, {kwargs}") | |
result = func(*args, **kwargs) | |
print(f"OUT fonc3b and return result of {func.__name__} exec") | |
return result | |
print("OUT deco3b") | |
return fonc3b |
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
>>> @deco3b | |
... def toto(): | |
... print("toto") | |
... | |
IN deco3b, ARG func = toto | |
IN deco3a, ARG func = fonc3b | |
OUT deco3a | |
OUT deco3b | |
>>> toto() | |
IN fonc3a and RUN func fonc3b with (), {} | |
IN fonc3b and RUN func toto with (), {} | |
toto | |
OUT fonc3b and return result of toto exec | |
OUT fonc3a and return result of fonc3b exec | |
>>> @deco3b | |
... def titi(a,b): | |
... print(f"{a} {b}") | |
... | |
IN deco3b, ARG func = titi | |
IN deco3a, ARG func = fonc3b | |
OUT deco3a | |
OUT deco3b | |
>>> titi("c'est parti", b="mon kiki") | |
IN fonc3a and RUN func fonc3b with ("c'est parti",), {'b': 'mon kiki'} | |
IN fonc3b and RUN func titi with ("c'est parti",), {'b': 'mon kiki'} | |
c'est parti mon kiki | |
OUT fonc3b and return result of titi exec | |
OUT fonc3a and return result of fonc3b exec |
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
# décorateur avec paramètres | |
def deco4param(param_in, param_out): | |
print(f"IN deco4param : {param_in}") | |
def deco4(func): | |
print(f"IN deco4, ARG func = {func.__name__}") | |
def fonc4(*args, **kwargs): | |
print(f"IN fonc4 and RUN func {func.__name__} with {args}, {kwargs}") | |
print(f"params : {param_in}, {param_out}") | |
result = func(*args, **kwargs) | |
print(f"OUT fonc4 and return result of {func.__name__} exec") | |
return result | |
print("OUT deco4") | |
return fonc4 | |
print(f"OUT deco4param : {param_out}") | |
return deco4 |
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
>>> @deco4param("input","output") | |
... def toto(pouet): | |
... print(pouet) | |
... | |
IN deco4param : input | |
OUT deco4param : output | |
IN deco4, ARG func = toto | |
OUT deco4 | |
>>> | |
>>> toto("hoho !") | |
IN fonc4 and RUN func toto with ('hoho !',), {} | |
params : input, output | |
hoho ! | |
OUT fonc4 and return result of toto exec |
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
# un décorateur avec paramètre qui inclus un autre décorateur avec paramètre | |
def deco5a_param(param_in, param_out): | |
print(f"IN deco5a_param : {param_in}") | |
def deco5a(func): | |
print(f"IN deco5a, ARG func = {func.__name__}") | |
def fonc5a(*args, **kwargs): | |
print(f"IN fonc5a and RUN func {func.__name__} with {args}, {kwargs}") | |
print(f"params : {param_in}, {param_out}") | |
result = func(*args, **kwargs) | |
print(f"OUT fonc5a and return result of {func.__name__} exec") | |
return result | |
print("OUT deco5a") | |
return fonc5a | |
print(f"OUT deco5a_param : {param_out}") | |
return deco5a | |
def deco5b_param(param_in, param_out): | |
print(f"IN deco5b_param : {param_in}") | |
def deco5b(func): | |
print(f"IN deco5b, ARG func = {func.__name__}") | |
def fonc5b(*args, **kwargs): | |
print(f"IN fonc5b and RUN func {func.__name__} with {args}, {kwargs}") | |
print(f"params : {param_in}, {param_out}") | |
result = func(*args, **kwargs) | |
print(f"OUT fonc5b and return result of {func.__name__} exec") | |
return result | |
print("OUT deco5b") | |
return (deco5a_param(param_in, param_out))(fonc5b) | |
print(f"OUT deco5b_param : {param_out}") | |
return deco5b |
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
>>> @deco5b_param("in","ou") | |
... def toto(a): | |
... print(a) | |
... | |
IN deco5b_param : in | |
OUT deco5b_param : ou | |
IN deco5b, ARG func = toto | |
OUT deco5b | |
IN deco5a_param : in | |
OUT deco5a_param : ou | |
IN deco5a, ARG func = fonc5b | |
OUT deco5a | |
>>> toto("haha") | |
IN fonc5a and RUN func fonc5b with ('haha',), {} | |
params : in, ou | |
IN fonc5b and RUN func toto with ('haha',), {} | |
params : in, ou | |
haha | |
OUT fonc5b and return result of toto exec | |
OUT fonc5a and return result of fonc5b exec |
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
import functools | |
# command = décorateur que l'on souhaite encapsuler/mettre en cache | |
def command(parameter=None): | |
def decorator(func): | |
print('Evaluate decorator') | |
def wrapped(*args, **kwargs): | |
print(f'Func called with parameter {parameter!r}') | |
return func(*args, **kwargs) | |
return wrapped | |
return decorator | |
# get_parameter sera mise en cache à la première exécution | |
# le cache sera utilisé pour les exécutions suivantes au lieu de get_parameter() | |
@functools.cache | |
def get_parameter(): | |
# Hard computation to get parameter | |
print('Make hard computation') | |
return (400 * 1291 * 13 - 1).to_bytes(3, 'big').decode() | |
# idem avec get_decorator (autnat de cache que d'appel de get_decorator un paramètre différent) | |
@functools.cache | |
def get_decorator(func): | |
# parameter de command est récupéré depuis get_parameter (ou depuis le cache) | |
decorator = command(parameter=get_parameter()) | |
return decorator(func) | |
def my_command(): | |
def decorator(func): | |
def wrapped(*args, **kwargs): | |
# on récupère get_decorator (ou son équivalent en cache) | |
new_func = get_decorator(func) | |
return new_func(*args, **kwargs) | |
return wrapped | |
return decorator | |
# le paramètre (get_parameter) à transmettre à 'command' est mise en cache | |
# le décorateur get_decorator(func) est mise en cache pour chaue func et appelera command avec get_parameter comme paramètre | |
@my_command() | |
def pouet(a, b): | |
return a + b | |
@my_command() | |
def toto(a, b): | |
return a - b | |
print('-' * 80) | |
print(pouet(1, 2)) | |
print(toto(1, 2)) | |
print(pouet(3, 4)) | |
print(toto(3, 4)) |
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
deco1 : identifications des éléments | |
deco2 : décorateur simple | |
deco3 : décorateurs qui inclus un autre décorateur | |
deco4 : décorateur avec paramètres | |
deco5 : décorateur avec paramètre qui inclus un autre décorateur avec paramètre | |
deco6 : décorateur avec mise en cache et incluant un autre décorateur |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment