[Python] Method decorators which "tag" method - prevent overwriting by other decorators

Discussão em 'Python' iniciado por Stack, Março 19, 2025.

  1. Stack

    Stack Membro Participativo

    I'm investigating the pattern whereby you have a method decorator which annotates the method in some way, and then once the class is defined it looks through its methods, finds the annotated methods, and registers or processes them in some way. e.g.

    def class_decorator(cls):
    for name, method in cls.__dict__.iteritems():
    if hasattr(method, "use_class"):
    # do something with the method and class
    print name, cls
    return cls

    def method_decorator(view):
    # mark the method as something that requires view's class
    view.use_class = True
    return view

    @class_decorator
    class ModelA(object):
    @method_decorator
    def a_method(self):
    # do some stuff
    pass


    (From here: https://stackoverflow.com/a/2367605/1256529)

    I wondered if anyone has a solution to the problem of multiple decorators. For example, this example works fine in isolation, but if I do the following, it will break because the use_class annotation will be hidden.

    def hiding_decorator(fn):
    def wrapper(*args, **kwargs):
    print("do some logging etc.")
    return fn(*args, **kwargs)
    return wrapper

    @class_decorator
    class ModelA(object):
    @hiding_decorator
    @method_decorator
    def a_method(self):
    # do some stuff
    pass



    Does anyone have a reliable and user-friendly way around this problem?

    Non-optimal solutions I can think of:

    • Dictate that your decorator should be outermost (but what if other decorators also have this requirement?)
    • Dictate that it only works with decorators that are transparent proxies for attributes of their inner functions/methods.
    • Require other decorators to be aware of the requirements of the tagging decorator (means generic utility decorators become difficult to use).

    None of these are particularly attractive.

    Continue reading...

Compartilhe esta Página