You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cherrypy中_cp_dispatch方法的异常行为问题

解决CherryPy中DispatchedFile1对象不可调用的TypeError问题

这个问题我之前也碰到过,本质是CherryPy对_cp_dispatch返回对象的处理规则没摸透~

问题根源

CherryPy通过_cp_dispatch拿到你返回的DispatchedFile1实例后,会按以下逻辑处理请求:

  1. 优先查找实例上**被@cherrypy.expose装饰、且方法名与HTTP请求方法完全一致(大写)**的方法(比如GET()对应GET请求);
  2. 如果找不到符合要求的方法,它会尝试把这个实例当作可调用对象直接执行;
  3. 而你的DispatchedFile1类既没有正确暴露对应HTTP方法的处理函数,也没有实现__call__方法,所以就抛出了TypeError: 'DispatchedFile1' object is not callable这类异常。

解决方案

方案1:为类添加对应HTTP方法的暴露函数

这是最符合CherryPy设计规范的方式,直接在DispatchedFile1类中定义大写的HTTP方法,并加上@cherrypy.expose装饰器:

import cherrypy

class DispatchedFile1:
    # 处理GET请求
    @cherrypy.expose
    def GET(self, **kwargs):
        # 这里写你的GET请求逻辑,比如读取文件内容
        return "处理GET请求:返回文件内容"
    
    # 处理POST请求
    @cherrypy.expose
    def POST(self, **kwargs):
        # 这里写你的POST请求逻辑,比如上传文件
        return "处理POST请求:上传文件成功"
    
    # 处理PUT请求
    @cherrypy.expose
    def PUT(self, **kwargs):
        # 这里写你的PUT请求逻辑,比如更新文件
        return "处理PUT请求:更新文件成功"
    
    # 处理DELETE请求
    @cherrypy.expose
    def DELETE(self, **kwargs):
        # 这里写你的DELETE请求逻辑,比如删除文件
        return "处理DELETE请求:删除文件成功"

class Root:
    def _cp_dispatch(self, vpath):
        # 根据你的路由逻辑返回DispatchedFile1实例
        # 比如匹配到特定路径时返回
        return DispatchedFile1()

if __name__ == "__main__":
    cherrypy.quickstart(Root())

方案2:让类实例可调用(统一处理所有HTTP方法)

如果你想在一个方法里统一处理所有HTTP请求,可以给DispatchedFile1类实现__call__方法,并确保它被@cherrypy.expose装饰:

import cherrypy

class DispatchedFile1:
    @cherrypy.expose
    def __call__(self, **kwargs):
        # 获取当前请求的HTTP方法
        current_method = cherrypy.request.method
        
        # 根据不同方法分支处理
        if current_method == "GET":
            return "通过__call__处理GET请求"
        elif current_method == "POST":
            return "通过__call__处理POST请求"
        elif current_method == "PUT":
            return "通过__call__处理PUT请求"
        elif current_method == "DELETE":
            return "通过__call__处理DELETE请求"
        else:
            return "不支持的请求方法"

class Root:
    def _cp_dispatch(self, vpath):
        return DispatchedFile1()

if __name__ == "__main__":
    cherrypy.quickstart(Root())

关键注意事项

  • 方法名必须是大写的GET/POST/PUT/DELETE,小写的get不会被CherryPy识别;
  • 所有处理请求的方法必须加上@cherrypy.expose装饰器,否则CherryPy会认为这是私有方法,不会用来处理请求;
  • 如果你的方法需要接收URL参数,建议加上**kwargs来兼容所有可能的参数,避免参数不匹配导致的错误。

内容的提问来源于stack exchange,提问作者LittleByBlue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:54:18