我正在编写一个可爱的应用程序,我想知道构建处理程序和代码的最佳方法是什么?
我认为通过cherrypy.root进行赋值很简单,但是编写处理程序并分配它们的一些做法是什么?
(请允许我证明我的困惑!) 我最初的想法是编写一个标准的处理程序类,它根据当前的URL或类/方法组合推断出要运行的模板。然后我会多次将该处理程序的一个实例分配给创建页面的路径。我不认为这有效,因为递归引用不能正常工作。
所以,鉴于我已经在绘制自己的源代码应该是什么样的空白,我会喜欢一些指针和示例!
随意提出一些详细问题让我澄清一下。虽然那里有大量的樱桃教程材料,但它往往只会划伤表面。
答案 0 :(得分:10)
CherryPy故意不要求你从框架提供的基类中继承子类,这样你就可以自由地设计自己的继承机制,或者更重要的是,根本不使用任何继承机制。您当然可以自由定义自己的基类并继承它;通过这种方式,您可以通过类的__init__
方法以及类级变量和方法来标准化处理程序构造和配置。
然而,首选方法是不同的。对于大多数Web应用程序,您实际上并不想改变处理程序的实际构造逻辑,也不关心类级变量或方法;相反,您需要每个URI或URI或每个站点的每个子树的可重用变量和方法,而不是每个类。您倾向于通过实例配置(处理程序元数据)和实例方法(处理程序逻辑)更改另一组处理程序中的一组处理程序。传统的基于类的继承可以做到这一点,但对于这种自定义来说,它是一种钝器。
因此,CherryPy旨在提供这种基于类的继承不能很好地进行的每资源集定制。它通过1)配置系统的设计提供了这一点,它允许您将元数据绑定到单个URI,URI的子树,处理程序的子树或具有相同语法的整个站点(请参阅http://docs.cherrypy.org/dev/intro/concepts/config.html以获取概述),以及2)钩子和工具系统,它允许您将逻辑绑定到单个URI,URI的子树,处理程序的子树或者整个网站。见http://docs.cherrypy.org/dev/intro/concepts/tools.html所以,实际上:在cherrypy.root
上使用普通属性来构建处理程序树:
def make_app():
root = Root()
root.foo = Foo()
root.bars = BarCollection()
return root
但是,不要让Root,Foo和Bar从公共基类继承。相反,编写独立的工具来执行“推断模板”之类的操作。也就是说,而不是:
from cherrypy import expose
class Foo(MyAppBase):
@expose()
def index(self, a, b, c):
...
root.foo = Foo(template='foo.html')
写:
from cherrypy import expose, tools
class Foo(object):
@tools.render(template='foo.html')
@expose()
def index(self, a, b, c):
...
root.foo = Foo()
...其中'tools.render'是您编写的CherryPy工具,用于查找并应用给定的模板。这种方法允许您覆盖配置文件中工具的参数,避免重新打包或修补代码:
[/foo/]
tools.render.template = 'foo2.html'
答案 1 :(得分:5)
这个问题非常主观 - 但我会试一试。
首先,始终将数据库和数据代码与Web代码分开。我所做的是在DB/
文件夹中有许多小文件,每个文件都有一个类,这些文件都连接在一起成为Base.py
文件,例如:
Web/
Base.py - The main "base" class, which includes the classes in other
web files, starts the web server in __init__
Users.py - The class which includes methods generally from "DB/Users.py"
which checks permissions etc before returning (you may
wish to add DB-level security later though)
...
DB/
Base.py - The main base DB class, includes the other DB classes. Creates
new SQLAlchemy/whatever instances and create database schemas if
they don't etc. May pay to have database-wide methods
here to keep creating connections etc in one place if you
decide to change databases later
Users.py - The user/password etc DB storage class file
...
Templates/
(HTML templates go here)
Static/
(Static images/CSS/javscript etc go here)
当然,不要忘记每个模块目录中的__init__.py
,以便python可以在子目录中找到模块
在我看来,用于构造代码的方法并不总是重要,但要保持一致。我写了一份包含我所有惯例的文件,并说明了我使用它们的理由,并尝试按照它们的意义进行操作,但一如既往a foolish consistency is the hobgoblin of small minds
,引用python style docs: - )< / p>
Class
,并仅通过模块名称引用它。我将举一个Base.py:import Users
class Base(Users.Class):
def __init__
(self):
Users.Class.__init__
(self)
的例子。
这有助于减少导入时其他模块互相引用的问题,因为如果__init__
__init__
from Users import Users
Users.py
会发生冲突,所以我总是按模块名称引用。这只是个人偏好,所以你想做什么:-P 希望你能从这篇文章中得到一个想法。