from functools import wraps
def foo_register(method_name=None):
"""Effectue des trucs."""
def decorator(method):
if method_name is None:
method.gw_method = method.__name__
else:
method.gw_method = method_name
@wraps(method)
def wrapper(*args, **kwargs):
method(*args, **kwargs)
return wrapper
return decorator
Exemple : Le code suivant décore my_function
avec foo_register
au lieu d'atteindre directement decorator
.
@foo_register
def my_function():
print('salut...')
Exemple : Le code suivant fonctionne comme prévu.
@foo_register('dire_bonjour')
def my_function():
print('salut...')
Si je veux que cela fonctionne correctement dans les deux applications (en utilisant method.__name__
et en passant le nom), je dois vérifier à l'intérieur de foo_register
si le premier argument est un décorateur, et si c'est le cas, je dois : return decorator(method_name)
(au lieu de return decorator
). Ce genre de "vérification si c'est callable" semble très bricolé. Y a-t-il un moyen plus élégant de créer un décorateur multi-usage comme celui-ci ?
P.S. Je sais déjà que je peux exiger l'appel du décorateur, mais ce n'est pas une "solution". Je veux que l'API soit naturelle. Ma femme adore décorer, et je ne veux pas gâcher cela.
2 votes
Voici la réponse. La fonction doit soit être une fonction de décorateur, soit une fonction qui renvoie une fonction de décorateur, et non pas magiquement l'une ou l'autre en fonction de ses arguments.
7 votes
@Glenn mais sa femme aime décorer. Et c'est un défi intéressant.
3 votes
Il ne me restait plus qu'à ajouter deux lignes de code supplémentaires (dans la réponse ci-dessous), ce qui équivaut à environ 180 octets d'économie. Cela signifie que je n'ai pas besoin d'acheter un nouveau disque dur, donc ma femme peut continuer à décorer.