繁体   English   中英

将函数传递到类中并将其用作类方法的装饰器

[英]passing function into a class and using it as a decorator of class methods

首先,我创建了一些我想在所有地方使用的用户管理功能,并将它们绑定到cherrypy,以为我可以将cherrypy导入其他地方并且它们在那里。 当不用作装饰器时,其他函数似乎可以这种方式导入。

from user import validuser
cherrypy.validuser = validuser
del validuser

那没有用,所以接下来我尝试将函数传递到该类中,该类是我的cherrypy网站( /analyze )的顶级页面类的一部分:

class Root:
    analyze = Analyze(cherrypy.validuser) #maps to /analyze

在分析课上,我提到了他们。 这适用于正常功能,但不适用于装饰器。 为什么不?

class Analyze:

    def __init__(self, validuser):
        self.validuser = validuser

    @cherrypy.expose
    @self.validuser(['uid'])
    def index(self, **kw):        
        return analysis_panel.pick_data_sets(user_id=kw['uid'])

我被卡住了。 如何传递函数并将其用作装饰器。 我不希望这样包装我的函数:

    return self.validuser(analysis_panel.pick_data_sets(user_id=kw['uid']),['uid'])

谢谢。

添加/编辑:这是装饰器正在做的事情,因为作为一个单独的问题,我认为它没有适当地将user_id添加到kwarg中

def validuser(old_function, fetch=['uid']):
    def new_function(*args, **kw):
        "... do stuff. decide is USER is logged in. return USER id or -1 ..."
        if USER != -1 and 'uid' in fetch:
            kw['uid'] = user_data['fc_uid']
        return old_function(*args, **kw)
    return new_function

只有传入的kwarg出现在new_function的kwarg中。 我尝试添加的任何内容都不存在。 (我在做什么似乎在这里起作用了。 如何在装饰器中将变量传递给装饰函数中的函数自变量?

CherryPy中处理此类情况的正确方法是拥有一个工具,并在需要身份验证的站点部分中启用该工具。 考虑首先创建此用户身份验证工具:

@cherrypy.tools.register('before_handler')
def validate_user():
    if USER == -1:
        return
    cherrypy.request.uid = user_data['fc_uid']

请注意, 在CherryPy 5.5.0中添加“注册”装饰器

然后,无论您想验证用户的哪个位置,都可以使用该工具装饰处理程序:

class Analyze:

    @cherrypy.expose
    @cherrypy.tools.validate_user()
    def index(self):
        return analysis_panel.pick_data_sets(user_id=cherrypy.request.uid)

或者在您的cherrypy配置中,启用该工具:

config = {
    '/analyze': {
        'tools.validate_user.on': True,
    },
}

函数/方法是在类中定义的,用实例变量来修饰它是没有意义的,因为对于每个实例,它不会是相同的修饰器。

您可以考虑在访问property使用property来创建装饰方法:

@property
def index(self):
    @cherrypy.expose
    @self.validuser(['uid'])
    def wrapped_index(**kw):
        return analysis_panel.pick_data_sets(user_id=kw['uid'])
    return wrapped_index

您可能还考虑尝试应用lru_cache为每个实例保存方法,但是我不确定如何将其与属性一起应用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM