status |
校对 |
完成度:85% |
PCS304 Python Web应用框架综论
- Web ~ 互联网的泛称;
- Web应用 ~ 基于互联网的应用简称;
- 框架 ~ Framework,是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架;(前者是从应用方面而后者是从目的方面给出的定义)
- 框架是可复用的设计构件库
- 框架就是某种应用的半成品
- 框架是一个可复用设计,由一组抽象类及其实例间协作关系来表达的
- 框架是在一个给定的问题领域内,一个应用程序的一部分设计与实现
- 框架是为解决代码复用问题的一个最靠谱的尝试
- 框架是,,,
- Python Web应用框架 ~ 由Python实现的面向互联网应用开发的框架!
- 对于开发者,就是一堆模块和使用这些模块的文档,基于这些框架,可以快速的完成有很高品质的互联网应用系统;而不用要求开发者有多么高深的相关领域经验;
- 可以说,框架就是游戏里的组合技,掌握了,就立即可以从菜鸟变成高手!
不过,在Python 世界,仅仅针对互联网应用的专门框架,就有不下20种!以至有人专门研究:"[http://xlp223.yculblog.com/post.1634226.html 为何有如此多的Python Web实用框架?]"
{{{脚注: 访问地址:http://xlp223.yculblog.com/post.1634226.html 精巧地址:http://tinyurl.com/6yajuo }}}
原文出处:[http://bitworking.org/news/Why_so_many_Python_web_frameworks Why so many Python web frameworks?]
{{{脚注: 访问地址:http://bitworking.org/news/Why_so_many_Python_web_frameworks 精巧地址:http://tinyurl.com/6kv9j3 }}} 在此文章中,作者为了展示任何人可以通过Python快速创建自个儿的Web应用框架, 当场使用 8个文件(6个Python脚本,一个页面模板文件,一个服务器脚本)创建并运行了一个含有足够功能的应用框架! 以些来回答了为何有如此多的Python Web实用框架?:
因为,实现一个忒简单了!
Joe Gregorio的超级框架
- 组成
model.py ~ 数据库设计模板脚本
dbconfig.py ~ 数据库连接配置脚本
manage.py ~ 服务管理脚本
1 import os, sys 2 3 def create(): 4 from sqlalchemy import Table 5 import model 6 for (name, table) in vars(model).iteritems(): 7 if isinstance(table, Table): 8 table.create() 9 10 def run(): 11 '''使用WSGI模式启动服务 12 ''' 13 import urls 14 if os.environ.get("REQUEST_METHOD", ""): 15 from wsgiref.handlers import BaseCGIHandler 16 BaseCGIHandler(sys.stdin, sys.stdout, sys.stderr, os.environ).run(urls.urls) 17 else: 18 from wsgiref.simple_server import WSGIServer, WSGIRequestHandler 19 httpd = WSGIServer(('', 8080), WSGIRequestHandler) 20 httpd.set_app(urls.urls) 21 print "Serving HTTP on %s port %s ..." % httpd.socket.getsockname() 22 httpd.serve_forever() 23 24 if __name__ == "__main__": 25 if 'create' in sys.argv: 26 create() 27 if 'run' in sys.argv: 28 run()
main.cgi ~ 服务器运行脚本
import manage manage.run()
urls.py ~ 基于URL的对象选择器
view.py ~ 基于WSGI应用的多个视图
1 import robaccia 2 import model 3 4 def list(environ, start_response): 5 rows = model.entry_table.select().execute() 6 return robaccia.render(start_response, 'list.html', locals()) 7 8 def member_get(environ, start_response): 9 id = environ['selector.vars']['id'] 10 row = model.entry_table.select(model.entry_table.c.id==id).execute().fetchone() 11 return robaccia.render(start_response, 'entry.html', locals()) 12 13 def create(environ, start_response): 14 pass 15 def create_form(environ, start_response): 16 pass 17 def member_edit_form(environ, start_response): 18 pass 19 def member_update(environ, start_response): 20 pass
robaccia.py ~ 模板处置脚本
1 import kid 2 import os 3 4 extensions = { 5 'html': 'text/html', 6 'atom': 'application/atom+xml' 7 } 8 9 def render(start_response, template_file, vars): 10 ext = template_file.rsplit(".") 11 contenttype = "text/html" 12 if len(ext) > 1 and (ext[1] in extensions): 13 contenttype = extensions[ext[1]] 14 15 template = kid.Template(file=os.path.join('templates', template_file), **vars) 16 body = template.serialize(encoding='utf-8') 17 18 start_response("200 OK", [('Content-Type', contenttype)]) 19 return [body]
list.html ~ 页面应用模板
<?xml version="1.0" encoding="utf-8"?> <html xmlns:py="http://purl.org/kid/ns#>"> <head> <title>A Robaccia Blog</title> </head> <div py:for="row in rows.fetchall()"> <h2>${row.title}</h2> <div>${row.content}</div> <p><a href="./${row.id}/">${row.updated}</a></p> </div> </html>
- 使用
创建数据库
~$ python manage.py create
通过交互环境,初始化数据
~$ python Python 2.4.3 (#2, Apr 27 2006, 14:43:58) [GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import model >>> i = model.entry_table.insert() >>> i.execute(id='first-post', title="Some Title", content="Some pithy text...", updated="2006-09-01T01:00:00Z") >>> i.execute(id='second-post', title="Moving On", content="Some not so pithy words...", updated="2006-09-01T01:01:00Z")
独立运行
~$ python manage.py run Serving HTTP on 0.0.0.0 port 8080 ...
- 也可以部署前述 main.cgi 到各种Web服务器中运行发布应用
- 能力
- 通过 SQLAlchemy 进行高效对象化的数据库操作
SQLAlchemy官方网站 http://www.sqlalchemy.org/
- 使用 WSGI(Web 服务器网关接口)模式运行
WSGI官方网站: http://www.wsgi.org/wsgi/What_is_WSGI
精巧地址: http://bit.ly/3IkgU4
- 可对URL进行映射管理
- 使用 Kid 模板系统,高效输出数据
Kid官方网站 http://www.kid-templating.org/
精巧地址: http://bit.ly/2YDxPd
- 通过 SQLAlchemy 进行高效对象化的数据库操作
是一个完备的,全功能Web应用框架!通过极少的配置和开发,就可以完成一个动态数据展示页面!
现状
正是因为使用Python 能够轻易的将各种即有模块组合出一个Web应用框架来;
所以,不象其它语言世界,仅仅有唯一或是极少数Web应用框架,,,
在Python 世界,有太多太多的应用框架,以致于大家被选择哪个所深深困惑! 即怕选择错框架,带来开发的麻烦;又怕一但选定了框架,将来享受不到其它框架更加美妙的特性,患得患失中,痛苦渡日;-)
这里行者们根据一些使用过的框架,综合考虑各种因素,大致的给出比较靠谱的Python Web应用框架理解来,以便帮助大家面对异常丰厚的Python Web应用框架,如何保持"平常心",正确对待各种框架;
回顾
按照笔者接触到框架的时间顺序来排列大致是这样的:
- Zope
- Twisted
- Snakelets
- Quixote
- Karrigell
- web.py
- Django
- Pylons
- Eurasia
- Web2py
- Uliweb 这里没有给出详细的开发社区情况,以及笔者体验框架的详细日期和情景,只是大致的列出先后接触/了解/应用框架的顺序;以此为基础,分享一点,对Python Web应用框架的体验:
- 各个框架都有鲜明的个性! 关注的问题领域各不相同;
- 各个框架都有明确的社区, 有专门的开发团队来维护~当然有的甚至于就是一个开发人员;
- 各个框架都能在不同程度上和其它框架/模块联用(这是Python 的胶水特质决定的);
分类
进一步的,根据前述"Joe Gregorio的超级框架",可以明确一个功能完备的Web应用框架,至少应该包含以下方面的功能支持:
- 服务发布
- URL分发
- 模板支持
- 数据库处理
各种框架一般前三个方面都支持的不错,根据对第4个方面的态度,那么可以大致将所有Python Web应用框架分成以下几类:
- 平台性框架
- 这类框架,认为框架不应该依赖数据库,是关注应用的高效构建和运行平台的;Zope和Twisted属于这类,都是非常深遂的框架!
- Zope 开发时间长,引发的影响大,甚至于有人认为:"未来互联网就是Zope";开创了一系列Web应用开发的新技术和理念,形成了宏大的社区和模块树; 虽然学习曲线实在太陡,但是过来人都说:"只要是作Web应用开发,学到底就会发现,其实一切都在Zope 中实现过了!"
- Twisted 也是老牌社区的作品,关注网络应用底层支持,支持几乎所有网络协议,关注企业级的网络服务构建;只是缺少立等可取的应用框架,一切都得用Twisted 去现实,算是提供了成套工具的钻石级工具箱!
- 轻小型框架
- 这类框架,认为数据库不是应用的必要因素,是关注友好快速的简单任务型网站开发的;CherryPy/Quixote/Karrigell/web.py等等都属于这类框架,标志特性是没有内置的数据库(类似MySQL 的关系型主流数据库)支持模块;
- 突出的共同特色有:
- 配置简便
- 模板系统简单轻便,或是可以自由使用外部模板系统
- 调试相对方便,有的甚至有专门的问题回溯机制
- 突出的共同特色有:
- 一站式框架
- 这类框架,认为数据库是应用的重要因素,是关注如何仅基于本身就可以快速独立的实现一个功能型网站;Django/TurboGears/Eurasia/UliWeb等等都属于这类框架;
- 突出的共同特色有:
- 有内置的ORM模块支持数据库的对象化操作;
- 有内置的事务性功能支持(比如说登录认证);
- 有高级的模板系统,支持复杂的页面组合,有的甚至于有内置的Ajax 页面动态效果支持;
- 突出的共同特色有:
选择
好的,即使可以快速理解现有的Py框架,但是也无法保证永远不再出现新好框架;所以,如何理性的靠谱的为自个儿的应用选择一个合适的框架?
- 笔者推荐一个思路
- 根据项目面对的问题域特性来进行评定,取舍!
- 核心问题:
A. 项目是否需要长期运营? B. 项目是否足够复杂多变?
- 就可以根据以下的判决矩阵进行决策:
问题状态 |
框架选择 |
|
A |
B |
|
Y |
Y |
平台型框架最佳 |
Y |
N |
轻小性框架即可,平台型框架最佳 |
N |
Y |
一站式架最佳 |
N |
N |
轻小性框架最佳 |
- 是综合考虑到以下因素,而总结的决策矩阵:
- 长期运营时,关键成本在维护,这要求框架足够稳定和容易谅解;
- 业务复杂时,关键成本在开发,这要求框架有足够的内置支持,以便减少开发投入;
- 平台型框架都有浑厚的积累,可以满足一切要求,但是需要一定的学习成本,以便恰当的运用好这些特性;
- 轻小型框架由于代码精悍,一般都有很好的负载能力,而且代码简洁,容易定制和扩展;
- 一站式框架,又分两类:
- 一则"All in one 式"的,任何方面功能都是自行开发内置包含的;
- 二则"Mix-in 式"的,多数方面功能是直接包含外部模块来配合完成的;
- "All in one 式"的胜在内部契合严密运行效率高!但是,一但有问题就非常难以清查,而且一般很难作到平滑的版本兼容;
- "Mix-in 式"的胜在选择自由,可以使用各种类似的自己熟悉的功能组件来替代默认的,学习成本小,而且各个组件可以单独升级,版本兼容危机小;但是,由于要兼顾各种组件接口,隐含的问题要多些;
- 前端模板系统,也分两类:
- 一则解释型的,需要动态加载Python 运行渲染出结果再输出;
- 二则编译型的,事先编译成可执行中间代码了,输出时可以直接融合入数据;
- 后者运行效率要高过前者,但是开发时,调试方面就是解释型的比编译型的要直观方便了;
- 功能网站的运行效率,很大部分就是和模板效率以及数据库处理效率相关! | +-- 如何来理解各种框架? | +-- 框架的框架 | +-- 轻型框架 | +-- 一站式框架 | \-- 模板系统 +-- 细说(按照历史顺序,选择经典框架来介绍,没有PCS独立章节的,和故事没有直接提及的)
探讨
Eurasia3 前面已经
- 用 895 行单文件实现了 ZODB
- 这次更过分了, Mako 只有 377 行。把类似于 Mako 的模板读进来, 解析成语法树, 然后编译成 Python 程序 (和 Mako 一样是编译型模板)
- 081020(16:24:22) 沈崴-wileishn:
支持 Mako 的 <%def name=""> <%call expr=""> <% python code %> ${...}
from template import compile, Template s = '''\ <%def name="test2(a, b)"> ${caller.test3()} or ${context.get('test3', None)()} %if a: ${a} %elif b: ${b} %else: <%write('hello')%> %endif %for i in xrange(100): ${str(i)} %endfor </%def> <%def name="test(c, d)"> <%call expr="test2(1, 2)"> <%def name="test3()"> <% x = 1 %> hello world! in test3 </%def> </%call> </%def> ''' print compile(s) m = Template(s) print m.test('aaa', 'bbb')
shelve2 已经在实用了。这个模板会被用在建立 Eurasia3 项目主站上
导读
- 总体回顾,给出相关阅读和思考指引
- Zope ~ 超浑厚框架 Jungyong Pan (100%)
Quxiote ~ 豆瓣动力核心 ~ QiangningHong(100%)
- Django~最流行框架快速体验教程 黄毅(100%)
- Eurasia ~ 关注高性能的原创框架 沈崴(100%)
UliWeb ~ 关注平衡感的自制框架 Limodou(100%)
深入探索Python的Web开发 HuangYi(100%)
Python Web应用框架纵论 :: +-- 导论 | +-- 现状 | \-- 为什么Python 中有这么多框架? +-- 分类 | +-- 如何来理解各种框架? | +-- 框架的框架 | +-- 轻型框架 | +-- 一站式框架 | \-- 模板系统 +-- 细说(按照历史顺序,选择经典框架来介绍,没有PCS独立章节的,和故事没有直接提及的) | +-- Zope/Plone (请潘俊勇撰写) | +-- Quixote (请 阿北或是朞其它豆瓣成员 撰写) | +-- Eruasia (请 沈崴 撰写) | +-- Django (HY自写) | \-- UliWeb (请Limodou撰写) +-- 选择 | +-- 个人 | +-- 团队 | \-- 企业 \-- 小结 \-- 选择的痛苦
反馈
创建 by -- ZoomQuiet [DateTime(2008-11-14T15:25:05Z)]