5

我正在编写一个樱桃应用程序,我想知道为大型应用程序构建处理程序和代码的最佳方法是什么?

我意识到通过cherrypy.root进行分配很简单,但是编写处理程序并分配它们的一些做法是什么?

(请允许我证明我的困惑!)我最初的想法是编写一个标准的处理程序类,它根据当前的 URL 或类/方法组合推断要运行的模板。然后我会多次将该处理程序的一个实例分配给创建页面的路径。但是,我认为这不起作用,因为递归引用无法正常工作。

所以,考虑到我已经在我自己的源代码的外观上画了个空白,我会喜欢一些指针和示例!

随时问一些详细的问题让我澄清。虽然那里有大量的樱桃教程材料,但它往往只触及表面。

4

2 回答 2

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'
于 2010-04-19T17:41:50.673 回答
5

这个问题非常主观 - 但我会试一试。

  • 首先,始终将数据库和数据代码与 Web 代码分开。我所做的是在一个DB/文件夹中有很多小文件,每个文件都有一个类,这些文件都连接到一个Base.py文件中,例如:

    网络/
        Base.py - 主要的“基”类,包括其他类
                  web 文件,启动 web 服务器__init__
        Users.py - 包含通常来自“DB/Users.py”的方法的类
                   在返回之前检查权限等(您可以
                   希望稍后添加 DB 级安全性)
        ...
    D B/
        Base.py - 主要的基本数据库类,包括其他数据库类。创建
                  新的 SQLAlchemy/whatever 实例并创建数据库模式,如果
                  他们没有等。可能需要支付数据库范围的方法
                  如果您在此处继续创建连接等
                  决定稍后更改数据库
        Users.py - 用户/密码等 DB 存储类文件
        ...
    模板/
        (HTML模板在这里)
    静止的/
        (静态图像/CSS/javscript 等到这里)
    
    当然不要忘记__init__.py每个模块目录中的,以便python可以在子目录中找到模块

  • 在我看来,你使用什么方法来构建代码并不总是重要的,但要保持一致。我用我所有的约定和我使用它们的理由编写了一个文档,并尝试遵循它们直到它有意义的点,但一如既往a foolish consistency is the hobgoblin of small minds,引用python 样式文档:-)

  • 尝试使用类而不是直接函数。对于小型项目可能无关紧要,但对于任何不平凡的事情都可能变得困难。我更喜欢有许多具有特定目的的文件,并且在一个文件中只有一个类,除非有多个文件是有意义的

  • 这可能是有争议的——我通常命名我的类Class,并通过模块名称来引用它。我将举一个 Base.py 的例子:
    import Users
    class Base(Users.Class):
        def __init__(self):
            Users.Class.__init__(self)
    
    这有助于减少其他模块在导入时相互引用时出现的问题,因为from Users import Users如果Users.py有冲突会发生冲突,from Base import x所以我总是按模块名称引用。这只是个人喜好,所以做你想做的:-P

希望你应该从这篇文章中得到一个想法。

于 2010-04-19T04:11:37.870 回答