Python Can';t在cherrpy应用程序(站点树)的导入子类中调用decorator

Python Can';t在cherrpy应用程序(站点树)的导入子类中调用decorator,python,class,cherrypy,python-decorators,Python,Class,Cherrypy,Python Decorators,我使用cherrypy作为web服务器,我想在返回页面之前检查用户的登录状态。这适用于主应用程序类(在site.py中)中的方法,但在网页树中更深一层的类(在单独的文件中)中对方法调用相同的修饰函数时会出现错误 validate\u user()是用作装饰器的函数。它要么将用户传递到页面,要么将其发送到401受限页面,作为cherrypy.Tool,如下所示: from user import validate_user cherrypy.tools.validate_user = cherry

我使用cherrypy作为web服务器,我想在返回页面之前检查用户的登录状态。这适用于主应用程序类(在
site.py
中)中的方法,但在网页树中更深一层的类(在单独的文件中)中对方法调用相同的修饰函数时会出现错误

validate\u user()
是用作装饰器的函数。它要么将用户传递到页面,要么将其发送到401受限页面,作为
cherrypy.Tool
,如下所示:

from user import validate_user
cherrypy.tools.validate_user = cherrypy.Tool('before_handler', validate_user)
我通过相应地将子类的实例指定为变量,将站点的不同部分附加到主
site.py
文件的应用程序类:

from user import UserAuthentication

class Root:
    user = UserAuthentication() # maps user/login, user/register, user/logout, etc
    admin = Admin()
    api = Api()

    @cherrypy.expose
    @cherrypy.tools.validate_user()
    def how_to(self, **kw):
        from other_stuff import how_to_page
        return how_to_page(kw) 
但是,当我尝试在管理或Api或分析部分中使用
validate\u user()
时,这不起作用。这些都在单独的文件中

import cherrypy

class Analyze:
    @cherrypy.expose
    @cherrypy.tools.validate_user() #### THIS LINE GIVES ERROR ####
    def explore(self, *args, **kw): # @addkw(fetch=['uid'])
        import explore
        kw['uid'] = cherrypy.session.get('uid',-1)
        return explore.explorer(args, kw)
错误在于cherrypy.tools没有validate_用户函数或方法。但我在site.py中指定的其他内容确实会出现在cherrypy中。为什么我不能在一个单独的文件中使用这个工具,这个文件是我整个站点地图的一部分

如果这是相关的,那么validate_user()函数只需查看cherrypy.request.cookie,找到“session_token”值,并将其与我们的数据库进行比较,如果ID匹配,则传递它


抱歉,我不知道Analyze()和Api()以及User()页面是子类,还是嵌套类,或者是扩展方法,或者是什么。所以我不能给这个确切的标题。我是否需要以某种方式将父类传递给它们?

这里的问题是Python在导入期间处理除函数/方法体之外的所有内容。因此,在
site.py
中,当您
import user
(或
from user import
)时,会导致在Python解释器获得
validate\u user
工具(包括试图通过值访问该工具的装饰器)的定义之前,处理所有
user
模块(而不是通过引用)

CherryPy有另一种机制,用于使用config来装饰函数,该机制将在这些处理程序上启用工具。请使用以下选项代替
@CherryPy.tools.validate\u user

@cherrypy.config(**{"tools.validate_user.on": True})
此修饰符之所以有效,是因为它不需要从
cherrypy.tools
访问
validate\u user
以在处理程序上安装自己,而是将cherrypy配置为稍后调用处理程序时在处理程序上安装该工具

如果该类上的所有方法都需要该工具,则可以在该类本身上使用该配置装饰器


您也可以为服务器配置中的给定端点启用该工具,如另一个问题中所述。

我应该注意,这是我之前问题的后续问题,并受此示例启发,其中是赋值
cherrypy.tools.validate\u user=cherrypy.tool('before\u handler',validate\u user')
正在发生?如果它不在第二个类运行时导入的模块中,则分配将永远不会发生,并且您将无法访问
validate\u user
decorator,即使您有权访问分配完成后的位置。只需在第二个类中添加额外的导入即可它也可能是一种迹象,表明您应该将装饰器放在其他地方,而不是写入
cherypy.tools
。分配
cherrypy.tools.validate\u user=cherrypy.Tool('before\u handler',validate\u user')
发生在site.py顶级文件中,该文件可能在服务器加载时加载(在调用第二个类实例化的根类之前)很棒——我将用它来装饰类本身,并尝试创建所有URL都需要验证的类。