簡體   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