##language:zh ''' 记录学习 CherryPy 自带的教程的心得 ''' -- ZoomQuiet [<>] <> = CherryPy教程 = == 有关教程 == 教程展示了 CherryPy 是如何工作的, 在学习本教程后,开发者应该可以利用 CherryPy 独有的途径来快速开发 Web 应用了! 假定你具有基本的Python 编程经验, 其实也不一定, 只是一定要对"面向对象编程思想"有足够的了解就可以开始学习CP2的愉快旅程了! == 知识准备 == * 假定读者具备以下条件: * 一些Python 编程知识; * 一些面向对象编程的经验; * 一些HTML 的经验,就对创建Web 页面是必须的. == 头一个CherryPy应用 == * {{{#!python #引入 CP2服务器对象 from cherrypy import cpg class HelloWorld: """声明一个HelloWorld对象 - 对象实例将由CherryPy发布 """ def index(self): """index()函式将解析为站点根请求 "/" - 比如说 "http://localhost/" - 这里仅仅是返回值字串 """ return "Hello world!" #这是必须的声明,通知CherryPy 将站点根页面发布 index.exposed = True # 没有发布内容的 web应用是不可接受的 # 发布 HelloWorld 类实例为站点根 cpg.root = HelloWorld() # 开始 CP2 服务守护 cpg.server.start(configFile="cp2.cfg") # 在 Unix 环境中,可以通过 Ctrl+C 或是直接杀进程来停止此次服务 # 当然你可以进一步的实现shutdown 函式在其中,只是这已经不在教程范围内了 # 默认的发布端口为 8000; 即,你可以在 http://localhost:8000/ 中看到结果 }}} === 概念 === * '''对象发布 (Publishing objects)''' * 任何对象都可以附加于 {{{cpg.root}}} 被称为'''已发布 (published)''',意思是对象可以执行 URL到对象 的映射,而不是对象本身可以忠诚老实直轄市的Web 访问,如果是那样的话叫'''已暴露 exposed''' * '''对象暴露 (Exposing objects)''' * CherryPy 将URL请求映射到对象,并自动执行函式,但是如果对应的函式本身成为Web请求的结果就称为 '''对象暴露 (Exposing objects)''' * 想 ''暴露对象'' 只要使用''exposed'' 属性 * {{{#!python @cpg.expose def index(self): ... }}} * (呜乎矣哉,好象没有用处,也没有尝试成功) * 这种写法可能就是decorator,2.4中才有的功能。不过我没有看过是不是这么回事。有时间我也学一学。 -- limodou * '''寻找当前对象 (Finding the correct object)''' * 对于用户 CP2的Web应用就象一个被静态文件中的web站点; * 各种请求都是从{{{cpg.root}}}开始寻找,直到有匹配 * {{{#!python cpg.root.onepage = OnePage() cpg.root.otherpage = OtherPage() }}} * 如上的声明将自动的把 ''http://localhost/onepage'' 指向第一个对象, * 而''http://localhost/otherpage'' 指向第二个对象, * 不过如下的声明:{{{#!python cpg.root.some = Page() cpg.root.some.page = Page() }}} * ''http://localhost/some/page'' 会指向{{{cpg.root.some.page}}} * '''索引函式 (The index method)''' * {{{index()}}} 函式在CherryPy 中有特殊的规则: * 就象''index.html''是内建对象树结点的默认页面 * 可以附加关键字参数,作为映射到表单的变量,来通过 '''GET'''和'''POST'''函式发送 * 调用其它函式 * CherryPy 当然也可以直接调用其它发布的对象 * {{{#!python def foo(): return 'Foo!' foo.exposed = True cpg.root.foo = foo }}} * 这里发布了一个 foo 对象,当 CherryPy 接受一个 ''/foo'' 请求时,将自动执行{{{foo()}}} * 注意这里''foo()''可以是一个普通函式,也可以是任何对象的函式,任何种类的调用都是允许的 == 从表单接受数据 == * {{{#!python class WelcomePage: #_cpFilterList = [EncodingFilter('utf8')] def index(self): # Ask for the user's name. return '''
What is your name?
''' index.exposed = True ... }}} * 如此就是可以直接输出表单为页面 * 然后:{{{#!python class Root: def doLogin(self, username=None, password=None): # check the username & password ... doLogin.exposed = True cpg.root = Root() }}} * 就可以接受 输入了! * 提醒的是编码问题,还是使用通常的专用中文 * 在脚本头部声明{{{ # -*- coding: gbk -*- }}} * 可以简单的保证一般性的页面请求,和输出问题 * 当然的,可以将外部准备好的HTML 文件作为信息来源直接 * {{{open("foo.html","r").read()}}}读入,然后随意的输出!哈哈哈! * 这可是比嵌入在页面的模板式编写要更加自然,可以随意处理! * 只是注意的是,与设计人员的衔接,当然,页面设计也应该都对象化,使用 DIV +CSS 进行组合! * 页面设计人员,应该说仅仅是CSS和图片的设计者!嗯嗯! ---- '''真正的惊奇之旅!''' == tutorial == ''随包提供的教程脚本,是体现Python 自说明的最好示范!'' * 对象==目录 * 页面==函式 * CherryPy 的简单新世界! * 多的一点基础是配置文件: * {{{ [server] socketPort = 9000 threadPool = 10 [session] storageType=ram }}} * 直观!我就修改了一下子 端口值,因为8000和8080都已经被占用了 === 01_helloworld.py === * 永远的信心!给予初学者! * 哈哈哈!第一位写'''Hello World!''' 的程序员如果要收版税的话,可能是古往今来最富的人了! === 02_expose_methods.py === * 也不用看,前面的简单分析后,是完全自然的 === 03_get_and_post.py === * 嗯嗯!完整的 CherryPy 美味哲学下的表单操作! * 看注释版本的代码最直接! * [[/03_get_and_post.py]] === 04_complex_site.py === * 咳咳咳,开始完整的站点展示了! * 通过简单的类继承,可以令所有页面拥有类似的页头,页尾! * 这比PHP使用 Includ 运算要更加OOP 是也乎! * 只是注意的是 不支持多重继承是也乎! * 嗬嗬嗬!居然可以有{{{Core Error dump...}}} 的反应,令Python 自杀了! * [[/04_complex_site.py]] === 05_derived_objects.py === * 对象的遗传! * 嗯嗯!简直是OOP编程的最直观展示! * 只是,不支持多重继承 * [[/05_derived_objects.py]] === 06_aspects.py === * 投影! * aspect 意义好多,看一下示范还是投影感觉对一些?! * [[/06_aspects.py]] === 07_default_method.py === * 默许函式处理 * [[/07_default_method.py]] * 可惜不能简单的支持中文的URL 请求 === 08_sessions.py === * 对话处理 * [[/08_sessions.py]] * 非常简单的处理!全局性的会话字典对象! * CherryPy 真的作到了自然的映射Pythonic 对象到web 应用请求! === 09_generators_and_yield.py === * 待续.... == bonus-sqlobject.py == * 数据库处理 * 要求安装 sqlobject