我使用flask
商店在redis
中构建限速装饰器,以识别不同端点上的不同限制。 (我意识到那里有很多限速装饰器,但是我的用例不同以至于我自己滚动它是有意义的。)
基本上我遇到的问题是确保我在redis中存储的密钥是特定于类的。我在烧瓶中使用蓝图模式,基本上是这样的:
class SomeEndpoint(MethodView):
def get(self):
# Respond to get request
def post(self):
# Respond to post request
这里的问题是我希望能够对这些类的post
方法进行速率限制,而无需添加任何其他命名约定。在我看来,最好的方法就是这样:
class SomeEndpoint(MethodView):
@RateLimit # Access SomeEndpoint class name
def post(self):
# Some response
但在装饰器中,只有post
函数在范围内。如果给定SomeEndpoint
函数,我将如何返回post
类?这是装饰器的基本布局。这可能令人困惑,所以这里是装饰者的一个更具体的例子。
class RateLimit(object):
"""
The base decorator for app-specific rate-limiting.
"""
def __call__(self, f):
def endpoint(*args, **kwargs):
print class_backtrack(f) # Should print SomeEnpoint
return f(*args, **kwargs)
return endpoint
基本上寻找class_backtrack
函数的样子。我已经查看了inspect
模块,但我还没有找到任何可以实现此目的的内容。
答案 0 :(得分:0)
您可以装饰整个类而不仅仅是方法:
def wrap(Class, method):
def wrapper(self, *args, **kwargs):
print Class
return method(self, *args, **kwargs)
return method.__class__(wrapper, None, Class)
def rate_limit(*methods):
def decorator(Class):
for method_name in methods:
method = getattr(Class, method_name)
setattr(Class, method_name, wrap(Class, method))
return Class
return decorator
@rate_limit('post')
class SomeEndpoint(object):
def post(self):
pass
class Subclass(SomeEndpoint):
pass
a = Subclass()
a.post()
# prints <class 'SomeEndpoint'>