передача функции декоратору в Cherrypy - PullRequest
0 голосов
/ 09 мая 2020

Как передать 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())

1 Ответ

2 голосов
/ 09 мая 2020

Вы должны использовать декоратор следующим образом:

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

Обратите внимание на отсутствие () после uppercase - декоратор принимает первый аргумент (декорированную функцию) неявно, и круглые скобки не нужны .

Изменить:

Согласно документации , инструмент можно определить с помощью декоратора 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!'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...