Faire des décorateurs avec des arguments optionnels

from functools import wraps

def foo_register(method_name=None):
    """Does stuff."""
    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: L'exemple suivant décore my_function avec foo_register au lieu de toujours le faire à decorator.

@foo_register
def my_function():
    print('hi...')

Exemple: L'exemple suivant fonctionne comme prévu.

@foo_register('say_hi')
def my_function():
    print('hi...')

Si je veux qu'il fonctionne correctement dans les deux applications (une à l'aide de method.__name__ et le passage le nom), je dois vérifier à l'intérieur de foo_register pour voir si le premier argument est un décorateur, et si oui, j'ai: return decorator(method_name) (au lieu de return decorator). Cette sorte de "check pour voir si c'est un callable" semble très hackish. Est-il une plus belle façon de créer un multi-usage décorateur, comme cette?

P. S. je sais déjà que je peux exiger le décorateur d'être appelé, mais ce n'est pas une "solution". Je veux l'API pour une sensation naturelle. Ma femme aime la décoration, et je ne veux pas gâcher ça.

  • C'est la réponse. La fonction doit être soit une fonction décorateur, ou une fonction qui retourne une fonction décorateur, pas par magie l'un ou l'autre selon ses arguments.
  • mais sa femme aime à décorer. Et c'est un défi intéressant.
  • Je n'ai eu qu'à ajouter deux lignes de code (en réponse ci-dessous), ce qui équivaut à environ 180 octets ou de l'épargne. Cela signifie que je n'ai pas à acheter un nouveau disque dur, afin que ma femme peut conserver décoration.
InformationsquelleAutor orokusaki | 2010-10-08