Can a decorator of an instance method access the class?

后端 未结 13 951
没有蜡笔的小新
没有蜡笔的小新 2020-11-27 12:33

I have something roughly like the following. Basically I need to access the class of an instance method from a decorator used upon the instance method in its definition.

13条回答
  •  日久生厌
    2020-11-27 13:15

    What flask-classy does is create a temporary cache that it stores on the method, then it uses something else (the fact that Flask will register the classes using a register class method) to actually wraps the method.

    You can reuse this pattern, this time using a metaclass so that you can wrap the method at import time.

    def route(rule, **options):
        """A decorator that is used to define custom routes for methods in
        FlaskView subclasses. The format is exactly the same as Flask's
        `@app.route` decorator.
        """
    
        def decorator(f):
            # Put the rule cache on the method itself instead of globally
            if not hasattr(f, '_rule_cache') or f._rule_cache is None:
                f._rule_cache = {f.__name__: [(rule, options)]}
            elif not f.__name__ in f._rule_cache:
                f._rule_cache[f.__name__] = [(rule, options)]
            else:
                f._rule_cache[f.__name__].append((rule, options))
    
            return f
    
        return decorator
    

    On the actual class (you could do the same using a metaclass):

    @classmethod
    def register(cls, app, route_base=None, subdomain=None, route_prefix=None,
                 trailing_slash=None):
    
        for name, value in members:
            proxy = cls.make_proxy_method(name)
            route_name = cls.build_route_name(name)
            try:
                if hasattr(value, "_rule_cache") and name in value._rule_cache:
                    for idx, cached_rule in enumerate(value._rule_cache[name]):
                        # wrap the method here
    

    Source: https://github.com/apiguy/flask-classy/blob/master/flask_classy.py

提交回复
热议问题