如何在cherrypy中设置'before_handler'的可调用函数参数

how to set the callable function parameters of 'before_handler' in cherrypy

def do_redirect(): raise cherrypy.HTTPRedirect("/login.html")

def check_auth(call_func): # do check ... if check_success(): return call_func() cherrypy.tools.auth = cherrypy.Tool('before_handler', check_auth) cherrypy.tools.auth.call_func = do_redirect

我想将函数 do_redirect 设置为 check_auth 的参数, 但它抛出以下异常: TypeError: check_auth() 恰好接受 1 个参数(给定 0)

但如果修改为遵循代码,它可以工作: def check_auth(call_func): # do check ... if check_success(): return cherrypy.tools.auth.call_func() cherrypy.tools.auth = cherrypy.Tool('before_handler', check_auth) cherrypy.tools.auth.call_func = do_redirect

如何在cherrypy中设置'before_handler'的可调用函数参数?

试试这个

cherrypy.tools.auth = HandlerWrapperTool(newhandler=auth_fn)

class AuthHandler(Tool):
    def __init__(self, auth_fn):
        self._point = 'before_handler'
        self._name = 'auth_handler'
        self._priority = 10
        self._auth_fn = auth_fn


    def callable(self):
        # implementation

有几种方法可以为工具设置参数,看看这个例子:

import cherrypy as cp


def check_success():
    return False

def do_redirect():
    raise cp.HTTPRedirect("/login.html")

def fancy_redirect():
    raise cp.HTTPRedirect("/fancy_login.html")

def secret_redirect():
    raise cp.HTTPRedirect("/secret_login.html")

def check_auth(call_func=do_redirect):
    # do check ...
    if check_success():
        return
    call_func()

cp.tools.auth = cp.Tool('before_handler', check_auth, priority=60)

class App:

    @cp.expose
    @cp.tools.auth() # use the default
    def index(self):
        return "The common content"

    @cp.expose
    def fancy(self):
        return "The fancy content"

    @cp.expose
    @cp.tools.auth(call_func=secret_redirect) # as argument
    def secret(self):
        return "The secret content"

    @cp.expose
    def login_html(self):
        return "Login!"

    @cp.expose
    def fancy_login_html(self):
        return "<h1>Please login!</h1>"

    @cp.expose
    def secret_login_html(sel):
        return "<small>Psst.. login..</small>"


cp.quickstart(App(), config={
    '/fancy': {
        'tools.auth.on': True,
        'tools.auth.call_func': fancy_redirect  # from config
    }
})