【发布时间】:2011-03-23 16:17:28
【问题描述】:
我正在尝试使用装饰器来管理用户可能会或可能不会访问网络应用程序(在 Google App Engine 上运行)中的资源的方式。请注意,我不允许用户使用他们的 Google 帐户登录,因此无法在 app.yaml 中设置对特定路由的特定访问权限。
我使用了以下资源:
- Bruce Eckel's guide to decorators
- SO : get-class-in-python-decorator2
- SO : python-decorators-and-inheritance
- SO : get-class-in-python-decorator
但是我还是有点迷茫……
这是我的代码!在以下示例中,current_user 是属于 RequestHandler 类的 @property 方法。它返回存储在数据存储中的 User(db.model) 对象,其级别为 IntProperty()。
class FoobarController(RequestHandler):
# Access decorator
def requiredLevel(required_level):
def wrap(func):
def f(self, *args):
if self.current_user.level >= required_level:
func(self, *args)
else:
raise Exception('Insufficient level to access this resource')
return f
return wrap
@requiredLevel(100)
def get(self, someparameters):
#do stuff here...
@requiredLevel(200)
def post(self):
#do something else here...
但是,我的应用程序对不同类型的资源使用不同的控制器。为了在所有子类中使用@requiredLevel 装饰器,我需要将其移至父类(RequestHandler):
class RequestHandler(webapp.RequestHandler):
#Access decorator
def requiredLevel(required_level):
#See code above
我的想法是使用以下代码访问所有控制器子类中的装饰器:
class FoobarController(RequestHandler):
@RequestHandler.requiredLevel(100)
def get(self):
#do stuff here...
我想我刚刚达到了我对装饰器和类继承的知识的极限:)。有什么想法吗?
【问题讨论】:
-
为什么是类上的方法?这只会导致事情崩溃,它只会像定义它的类中的常规函数一样工作。除非你使用的是 3.x,在这种情况下它可能会正常工作。
-
装饰器是类上的一个方法,因为我还没有想出如何将装饰器编码为一个类 1/ 接受参数和 2/ 可以访问当前类的方法本身。这是你的意思吗?由于主要是自学成才,我无法完全理解 Bruce Eckell 的指南、装饰器和继承。
-
你可以在课堂外复制粘贴函数,它会正常工作。这足以回答您的问题吗?
-
将 requiredLevel 装饰器从 FoobarController 移动到 RequestHandler 并用@staticmethod 装饰它似乎是根据stackoverflow.com/questions/3001138/… 的解决方案,但是在我的情况下它并不能解决问题。很可能是因为我的装饰器接受参数?
-
不,我的意思是把它从课堂上完全删除。使其成为常规功能。
标签: python web-applications decorator subclassing