#language zh '''记录学习 CherryPy 自带的教程的心得 ''' -- ZoomQuiet [<>] <> = CherryPy教程 = == 有关教程 == 教程展示了 CherryPy 是如何工作的, 在学习本教程后,开发者应该可以利用 CherryPy 独有的途径来快速开发 Web 应用了! 假定你具有基本的Python 编程经验, 其实也不一定, 只是一定要对"面向对象编程思想"有足够的了解就可以开始学习CP2的愉快旅程了! == 知识准备 == * 假定读者具备以下条件: * 一些Python 编程知识; * 一些面向对象编程的经验; * 一些HTML 的经验,就对创建Web 页面是必须的. == 头一个CherryPy应用 == * {{{ #!python #引入 CP2服务器对象 import cherrypy class HelloWorld: """声明一个HelloWorld对象 - 对象实例将由CherryPy发布 """ def index(self): """index()函式将解析为站点根请求 "/" - 比如说 "http://localhost/" - 这里仅仅是返回值字串 """ return "Hello world!" #这是必须的声明,通知CherryPy 将站点根页面发布 index.exposed = True # 没有发布内容的 web应用是不可接受的 # 发布 HelloWorld 类实例为站点根 cherrypy.root = HelloWorld() # 开始 CP2 服务守护 cherrypy.server.start(configFile="cp2.cfg") # 在 Unix 环境中,可以通过 Ctrl+C 或是直接杀进程来停止此次服务 # 当然你可以进一步的实现shutdown 函式在其中,只是这已经不在教程范围内了 # 默认的发布端口为 8000; 即,你可以在 http://localhost:8000/ 中看到结果 }}} === 概念 === * '''对象发布 (Publishing objects)''' * 任何对象都可以附加于 {{{cherrypy.root}}} 被称为'''已发布 (published)''',意思是对象可以执行 URL到对象 的映射,而不是对象本身可以忠诚老实直�市的Web 访问,如果是那样的话叫'''已暴露 exposed''' * '''对象暴露 (Exposing objects)''' * CherryPy 将URL请求映射到对象,并自动执行函式,但是如果对应的函式本身成为Web请求的结果就称为 '''对象暴露 (Exposing objects)''' * 想 ''暴露对象'' 只要使用''exposed'' 属性 * {{{ #!python @cherrypy.expose def index(self): ... }}} * (呜乎矣哉,好象没有用处,也没有尝试成功) * (原文已经说了是decorator, 这样的话就要求python的版本为2.4了 - limodou) * '''寻找当前对象 (Finding the correct object)''' * 对于用户 CP2的Web应用就象一个被静态文件中的web站点; * 各种请求都是从{{{cherrypy.root}}}开始寻找,直到有匹配 * {{{ #!python cherrypy.root.onepage = OnePage() cherrypy.root.otherpage = OtherPage() }}} * 如上的声明将自动的把 ''http://localhost/onepage'' 指向第一个对象, * 而''http://localhost/otherpage'' 指向第二个对象, * 不过如下的声明: {{{ #!python cherrypy.root.some = Page() cherrypy.root.some.page = Page() }}} * ''http://localhost/some/page'' 会指向{{{cherrypy.root.some.page}}} * '''索引函式 (The index method)''' * {{{index()}}} 函式在CherryPy 中有特殊的规则: * 就象''index.html''是内建对象树结点的默认页面 * 可以附加关键字参数,作为映射到表单的变量,来通过 '''GET'''和'''POST'''函式发送 * 调用其它函式 * CherryPy 当然也可以直接调用其它发布的对象 * {{{ #!python def foo(): return 'Foo!' foo.exposed = True cherrypy.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 cherrypy.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 == Continuation == * cherryflow 示例: {{{ def query(self): phones = {'albert': '134663', 'ying':'133'} yield '''
Name:
''' % cherrypy.request.resume_id name = cherrypy.request.paramMap.get("name") if name in phones.keys(): yield name, phones[name] else: yield """Not found
query = cherrypy.expose(cherryflow.flow(query)) }}} == 反馈 == * 我把歌词查询的东西用CP2实现了web查询,蛮简单的 * 如何处理用户登陆等,cookie什么的 -- Dreamingk * 处理session可以使用`cherrypy.sesion`,但前提是打开 session_filter 配置 * 处理cookie可以使用 `cherrypy.response.simple_cookie`, `cherrypy.request.simple_cookie` * 不错啊,现在也有CHERRY的教程了