Archive for the ‘技术’ Category
Django的Middleware开发有感
此文来自本人原JavaEye博客,发表于2009年2月26日。原文地址
Django应该算是目前最火的Pyhton的Web框架了把。个人感觉,超级方便的ORM,清晰而功能明确的分层以及Killer级别的后台管理都让习惯了Java那一套庞大复杂的人有了眼前一亮的感觉。
不过用久了就会发现,django整个框架之中有一个极其繁琐的地方,就好像一块整洁的布上有一个污点一样,令人觉得不爽。
那就是他的URL机制。。当然,也有人非常喜欢他的URL机制,比如说十分的灵活。不过我个人总觉得还有改进的地方。
首先我认为必须要利用正则表达式这一点,这个是特色以及精华,并且确实十分方便,在我眼里属于不能更改的部分。那么自然而然改进的地方就是正则表达式和函数的映射了。
提出问题是一方面,解决问题就是更加重要的地方了。采用何种新的方式来替换原来的URL处理呢?我为此困扰了好久。直到有一天发现了limodou大牛的Uliweb框架。被它的简洁明了的URL方式吸引了。决定采用类似Uliweb的方式处理URL。实现的具体细节,就是用Django的中间件。
使用中间件自然有他的理由。研究官网的文档后发现,Django处理一个Request的过程是首先通过中间件,然后再通过默认的URL方式进行的。所以说我们要做的就是在Middleware这个地方把所有Request拦截住,用我们自己的方式完成处理以后直接返回Response。需要注意的是,因为我不舍得放弃Killer级别的Admin,所以必须要支持默认的URL配置方式。那么我们可以简化原来的设计思路,把中间件不能处理的Request统统不管,丢给Django去处理。简直是完美的解决方案。:)。同时也不得不赞一声Django的设计。
接下来的设计就是考虑URL和函数处理的问题了。这个时候应该感谢的就是Python强大的语法了。提供了Decorator这种机制来解决这个问题。那么设计的思路转变成,在Request到达Middleware的时候,Import所有INSTALLED_APPS里面的views.py,目的自然就是执行Decorator。而在Decorator内部,根据到达的Request获得其访问地址,然后和处理它的函数一起生成RegexURLPattern对象,储存在缓存中。然后对每个Request进行处理,符合规则的就调用函数处理,不符合规则的,就交给Django自己去处理了。
以下是一小段中间件代码。比较核心的部分了。其实代码量也不大。大家看看有没有实现的问题。
def process_request(self,request):
path=request.path_info #获得request的地址
urls=settings.INSTALLED_APPS #获得当前安装的app的位置
def myimport(path):
try:
__import__('%s.views'%path) #读取所有app的views。。目的是注册request处理函数
except:
pass
map(myimport,urls) #执行所有
callback=expose.getCallback(path) #获取相应url对应的处理函数
if callback:
return callback[0](request) #执行。。
整体设计大致如此,完成了0.1版本,已经放在我的代码库里面了.http://code.google.com/p/linllx/
目前还存在的问题就是。第一,对于需要命名分组的正则表达式的处理还不是很有头绪。第二,对于404错误的处理究竟要如何进行,目前的实现来看不是很好。请看见本文的牛人们提供一下思路。。
总得来说,Django中间件的开发并不像我想像中的那么难,甚至可以说,还是比较简单的。下一步着手开发一个类似于Java中的Filter的中间件把。。当然,这个还是需要继续完善的。。
使用greenlet中一点简单心得
想要对greenlet的switch机制进行测试,于是写了以下这段代码。
from greenlet import *
def test1(x, y):
print 'in test1'
z = gr2.switch(x+y)
print z
print 'out test1'
def test2(u):
print 'in test2'
print u
gr1.switch(42)
print 'out test1'
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch("hello", " world")
运行结果:
in test1
in test2
hello world
42
out test1
从这个层面可以看出。greenlet的协程其实是一个切换机制。就是主动将自己的运行过程让给别的协程。切换需要有目标,并且可以在switch里面传入参数。如果是第一次运行,switch的参数就是作为协程的run的函数的参数传入。如果是运行中,就作为switch的返回值。
以上隐含的内容是,如果在运行中想要切换到别的协程去做事,那么不能保证那个协程一定会返回结果。
考虑在greenlet上面加上一个隐含回复机制。