构建cherrypy应用程序有哪些最佳实践?

时间:2010-04-18 17:38:39

标签: python cherrypy program-structure

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

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

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

所以,鉴于我已经在绘制自己的源代码应该是什么样的空白,我会喜欢一些指针和示例!

随意提出一些详细问题让我澄清一下。虽然那里有大量的樱桃教程材料,但它往往只会划伤表面。

2 个答案:

答案 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

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