使用python的GAE中具有@cached_属性的请求处理程序

使用python的GAE中具有@cached_属性的请求处理程序,python,google-app-engine,Python,Google App Engine,很抱歉,我问了个书呆子问题,但我花了2天时间,但找不到任何解决方案 这是我的route.py配置 app = WSGIApplication( routes=[ Route("/account", handler="app.account.Settings") ] ) 我创建了一个需要登录的处理程序 @HealthPortRequestHandler.login_required class Settings(HealthPortRequestHandler):

很抱歉,我问了个书呆子问题,但我花了2天时间,但找不到任何解决方案

这是我的route.py配置

app = WSGIApplication(
    routes=[
        Route("/account", handler="app.account.Settings")
    ]
)
我创建了一个需要登录的处理程序

@HealthPortRequestHandler.login_required
class Settings(HealthPortRequestHandler):
    def get(self):
        self.render("account/settings.html")
并创建登录所需的验证方法

@cached_property
    def check_user_logged_in(self):
        if self.request.cookies.get("User"):
            user_id = self.read_cookie("User")
            if user_id:
                from models.users import Users
                return Users.get_by_id(int(user_id))
            else:
                return None
        return None

    @staticmethod
    def login_required(handler):
        def check_login(self, *args, **kwargs):
            if self.check_user_logged_in:
                return handler(self, *args, **kwargs)
            else:
                return self.redirect("/login")
        return check_login
但在此行调试时发现错误

if self.check_user_logged_in:
错误地 提高属性错误属性

AttributeError: check_user_logged_in

我怎么知道到底发生了什么?有什么想法吗?

您正在将所需的decorator登录应用于类设置,因此在创建设置实例时将执行decorator

当您尝试创建设置实例时,将调用login\u required中的check\u login函数。它接收的参数是传递给设置的_init__方法的值。check_login然后将收到的第一个值作为参数,并尝试访问其check_user_logged_in属性。此值(不管它可能是webapp2.Request对象)没有check\u user\u logged\u属性,因此引发异常

这可以在不使用webapp2框架的情况下进行演示:

class HealthPortRequestHandler(object):

    def __init__(self, *args, **kwargs):
        pass

    @property
    def check_user_logged_in(self):
        pass

    @staticmethod
    def login_required(handler):
        def check_login(self, *args, **kwargs):
            if self.check_user_logged_in:
                return handler(self, *args, **kwargs)
            else:
                raise RuntimeError('Not expecting to execute this')
        return check_login   


@HealthPortRequestHandler.login_required
class Settings(HealthPortRequestHandler):
    pass

>>> s = Settings('Hello')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "demo.py", line 14, in check_login
    if self.check_user_logged_in:
AttributeError: 'str' object has no attribute 'check_user_logged_in'

>>> s = Settings(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "demo.py", line 14, in check_login
    if self.check_user_logged_in:
AttributeError: 'int' object has no attribute 'check_user_logged_in'

>>> s = Settings('Hello', 5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "deco.py", line 14, in check_login
    if self.check_user_logged_in:
AttributeError: 'str' object has no attribute 'check_user_logged_in'
这就是为什么你会得到AttributeError


为了修复它,我建议装饰请求处理程序的分派方法,而不是类定义。这样,您仍然可以在处理请求之前进行检查,但可以访问完全初始化的设置实例。

但是无论如何,我按照您的建议修复了我的代码:class SettingsHealthPortRequestHandler:@HealthPortRequestHandler.login\u必需的def getself:self.renderaccount/Settings.html