CherryPy中如何将index()传递给uppercase装饰器实现结果大写?
解决CherryPy装饰器导致的500 Internal Server Error问题
我来帮你搞定这个报错!先拆解下问题:你遇到的TypeError: uppercase() missing 1 required positional argument: 'func',核心原因是混淆了普通Python装饰器和CherryPy工具钩子的写法规则。
错误根源分析
你写的uppercase(func)是标准的普通函数装饰器结构——接收被装饰的函数作为参数,返回包装后的函数。但你把它注册成了CherryPy的before_finalize工具钩子,而CherryPy的钩子函数在触发时,并不会把视图函数传递给它,所以就出现了参数缺失的报错。
两种修正方案
方案1:正确适配CherryPy的before_finalize钩子
既然你想用CherryPy的工具钩子在请求处理的最后阶段修改响应内容,直接操作CherryPy的响应对象就行,不需要接收视图函数:
import cherrypy def uppercase(): # before_finalize阶段,视图函数已经执行完,响应体已生成 # 注意response.body是字节数组,先转成字符串处理 original_content = cherrypy.response.body[0].decode('utf-8') modified_content = original_content.upper() # 再转回字节数组赋值回去 cherrypy.response.body = [modified_content.encode('utf-8')] # 注册为before_finalize阶段的工具 cherrypy.tools.uppercase = cherrypy.Tool('before_finalize', uppercase) class HelloWorld(object): @cherrypy.expose @cherrypy.tools.uppercase() def index(self): return 'Hello!' if __name__ == '__main__': cherrypy.quickstart(HelloWorld())
方案2:改用普通函数装饰器(更适合单个视图的场景)
如果你只是想给特定视图函数的返回值转大写,直接用普通装饰器更简单,不需要注册CherryPy工具:
import cherrypy def uppercase(func): def wrapper(*args, **kwargs): # 接收视图函数的所有参数,执行原函数 original_result = func(*args, **kwargs) # 转大写后返回 return original_result.upper() return wrapper class HelloWorld(object): @cherrypy.expose @uppercase # 这里直接用装饰器,不要加括号! def index(self): return 'Hello!' if __name__ == '__main__': cherrypy.quickstart(HelloWorld())
为什么原来的代码不行?
你之前既想把它当成普通装饰器(接收func参数),又想把它注册成CherryPy的工具钩子,两种模式的参数规则不兼容,才导致了参数缺失的错误。选上面任意一种方案,都能解决这个500错误。
内容的提问来源于stack exchange,提问作者jeril
相关产品推荐
相关产品推荐

