Xua*_*uan 6 python cherrypy flask
默认的CherryPy路由样式基于带有方法的类的实例@cherrypy.expose.
在下面的示例中,这些URL是通过对其他普通类进行简单调整来提供的.
/
/hello
/hello/again
/bye
/bye/again
Run Code Online (Sandbox Code Playgroud)
我想知道是否有办法使用Flask的@route或其他一些装饰器来实现这一点.
import cherrypy
class Root(object):
@cherrypy.expose
def index(self):
return 'my app'
class Greeting(object):
def __init__(self, name, greeting):
self.name = name
self.greeting = greeting
@cherrypy.expose
def index(self):
return '%s %s!' %(self.greeting, self.name)
@cherrypy.expose
def again(self):
return '%s again, %s!' %(self.greeting, self.name)
if __name__ == '__main__':
root = Root()
root.hello = Greeting('Foo', 'Hello')
root.bye = Greeting('Bar', 'Bye')
cherrypy.quickstart(root)
Run Code Online (Sandbox Code Playgroud)
为了做这样的事情,你必须使用一些 Python 魔法,但是,使用 Flask 绝对可以做到。复制示例的最直接方法是子类 Flask。这是一种方法:
import inspect
from flask import Flask
def expose(f):
"""Decorator that flags a method to be exposed"""
f._exposed_method = True
return f
class FlaskOfCherryPy(Flask):
"""Custom flask that allows cherrypy's expose decorator"""
def quickstart(self, root_handler, *args, **kwargs):
self._process_root_handler(root_handler)
self.run(*args, **kwargs)
def _process_root_handler(self, root_handler):
# Prime the recursive processing
root_url = []
self._process_a_handler(root_handler, root_url)
def _process_a_handler(self, current_handler, url_stack):
# This gives a list of all the members of current_handler
members = inspect.getmembers(current_handler)
for name, value in members:
# You probably want to skip things that start with a _ or __
if name.startswith('_'):
continue
# Check if the method is decorated
is_exposed_method = getattr(value, '_exposed_method', False)
# If it's a callable with the _exposed_method attribute set
# Then it's an exposed method
if is_exposed_method and callable(value):
self._add_exposed_url(url_stack, name, value)
else:
new_stack = url_stack[:]
new_stack.append(name)
self._process_a_handler(value, new_stack)
def _add_exposed_url(self, url_stack, name, view_func):
copied_stack = url_stack[:]
if name != 'index':
copied_stack.append(name)
url = "/%s" % "/".join(copied_stack)
if name == 'index':
copied_stack.append(name)
view_name = "_".join(copied_stack)
self.add_url_rule(url, view_name, view_func)
class Root(object):
@expose
def index(self):
return 'my app'
class Greeting(object):
def __init__(self, name, greeting):
self.name = name
self.greeting = greeting
@expose
def index(self):
return '%s %s!' %(self.greeting, self.name)
@expose
def again(self):
return '%s again, %s!' %(self.greeting, self.name)
if __name__ == '__main__':
root = Root()
root.hello = Greeting('Foo', 'Hello')
root.bye = Greeting('Bar', 'Bye')
app = FlaskOfCherryPy(__name__)
app.quickstart(root)
Run Code Online (Sandbox Code Playgroud)
本质上,技巧是获取所有用该
_exposed_method属性标记的方法并将它们传递给Flask.add_url_rule
(请参阅此处的文档)。Flask 的美妙之处在于它是一个轻量级的系统,扩展它并不是很可怕。我强烈建议你深入思考并尝试一下,但我很高兴解决你的问题,所以我在这里将脚本作为要点。
我编写的这段特定代码并不完美,也没有经过严格测试,但它绝对适用于您的特定用例。此外,这不一定是您希望在生产环境中运行应用程序的方式。您必须创建某种应用程序工厂才能做到这一点。再次,我强烈建议您研究一下 Flask 的内部结构,让它按照您想要的方式工作。您可能还想查看 Flask 提供的基于类的视图或蓝图。他们能够做一些与你们这里的事情类似的事情。诚然,使用它们是非常不同的,而且我知道使用普通蓝图不可能设置实例属性。再说一次,你可以随时延长:-)
| 归档时间: |
|
| 查看次数: |
698 次 |
| 最近记录: |