【问题标题】:passing function to a decorator in cherrypy将函数传递给cherrypy中的装饰器
【发布时间】:2020-05-09 12:02:51
【问题描述】:

如何将index() 传递给名为uppercase() 的装饰器函数。我希望从index() 传递的值大写。

我收到此错误:

500 Internal Server Error
The server encountered an unexpected condition which prevented it from fulfilling the request.

Traceback (most recent call last):
  File "/home/user/.local/lib/python3.6/site-packages/cherrypy/_cprequest.py", line 638, in respond
    self._do_respond(path_info)
  File "/home/user/.local/lib/python3.6/site-packages/cherrypy/_cprequest.py", line 701, in _do_respond
    self.hooks.run('before_finalize')
  File "/home/user/.local/lib/python3.6/site-packages/cherrypy/_cprequest.py", line 95, in run
    self.run_hooks(iter(sorted(self[point])))
  File "/home/user/.local/lib/python3.6/site-packages/cherrypy/_cprequest.py", line 117, in run_hooks
    hook()
  File "/home/user/.local/lib/python3.6/site-packages/cherrypy/_cprequest.py", line 65, in __call__
    return self.callback(**self.kwargs)
TypeError: uppercase() missing 1 required positional argument: 'func'

import cherrypy
from cherrypy import tools

@cherrypy.tools.register('before_finalize')
def uppercase(func):
    def wrapper():
        original_result = func()
        modified_result = original_result.upper()
        return modified_result
    return wrapper

class HelloWorld(object):
    @cherrypy.expose
    @cherrypy.tools.uppercase()
    def index(self):
        return 'Hello!'


if __name__ == '__main__':
    cherrypy.tools.uppercase = cherrypy.Tool('before_finalize', uppercase)
    cherrypy.quickstart(HelloWorld())

【问题讨论】:

  • 请将完整的错误回溯添加到您的问题中!
  • @cherrypy.tools.uppercase() 中删除(),装饰器被隐式调用,其装饰的函数作为第一个参数。您在没有参数的情况下显式调用它,这就是为什么您会看到错误“缺少 1 个必需的位置参数”。
  • TypeError:“大写”工具不接受位置参数;你必须使用关键字参数。

标签: python cherrypy


【解决方案1】:

你应该像这样使用装饰器:

@cherrypy.tools.uppercase
def index(self):
    return 'Hello!'

请注意uppercase 之后缺少() - 装饰器隐含地采用第一个参数(被装饰的函数),并且不需要括号。

编辑:

根据the documentation,可以使用cherrypy.tools.register 装饰器或cherrypy.Tool 构造器来定义工具。在您的代码中,您定义了两次 uppercase 工具。

但是,在您的情况下,uppercase 装饰器不需要定义为 Tool,因为它不需要每次都作为挂钩 (before_finalize) 运行。

因此,最好将它用作普通的 Python 装饰器,如下所示:

from functools import wraps

# just a plain Python decorator
def uppercase(func):
    @wraps(func) #preserve function attributes, such as its name
    def wrapper(*args):
        original_result = func(*args)
        modified_result = original_result.upper()
        return modified_result
    return wrapper

class HelloWorld(object):
    @cherrypy.expose
    @uppercase # decorated once, the exposed function is now uppercase(index) 
    def index(self):
        return 'Hello!'

【讨论】:

  • 我试过了,但我得到了这个错误 TypeError: The 'uppercase' Tool doesn't accept positional arguments;你必须使用关键字参数。
  • @jeril 我更新了答案,检查这种方法是否有帮助。
  • 不行..用普通的 python 装饰器尝试过.. TypeError: wrapper() 接受 0 个位置参数,但给出了 1 个
  • @jeril 当然,我的错,包装器假定装饰函数不带参数,但它确实带“self”。您可以将 *args 添加到包装器的定义和内部的 func 调用中。
猜你喜欢
  • 2021-11-15
  • 2021-11-21
  • 1970-01-01
  • 2016-01-30
  • 1970-01-01
  • 2010-12-30
  • 1970-01-01
  • 2016-02-14
  • 2014-11-17
相关资源
最近更新 更多