python web框架 编写_Python学习 - 编写一个简单的web框架(一)

自己动手写一个web框架,因为我是菜鸟,对于python的一些内建函数不是清楚,所以在写这篇文章之前需要一些python和WSGI的预备知识,这是一系列文章。这一篇只实现了如何处理url。

预备知识

web框架主要是实现web服务器和web应用之间的交互。底层的网络协议主要有web服务器完成。譬如监听端口,填充报文等等。

Python内建函数__iter__和__call__和WSGI

迭代器iterator

迭代器为类序列对象提供了类序列的接口,也就是说类序列对象可以通过迭代器像序列一样进行迭代。说简单一点就是遍历对象。如果想让类是可迭代的,那么就必须实现__iter__和next()。

__call__

只要在类定义的时候实现了__call__方法,那么该类的对象就是可调有的,即可以将对象当做函数来使用。这里只用明白什么是__call__函数即可,因为WSGI规范中用要求。

WSGI

关于WSGI的介绍可以点击http://webpython.codepoint.net,有很详细的介绍。这里只说明一下大概。WSGI接口是用可调用的对象实现的:一个函数,一个方法或者一个可调用的实例。下面是一个实例,注释写的很详细:

# This is our application object. It could have any name,

# except when using mod_wsgi where it must be "application"

def application( # It accepts two arguments:

# environ points to a dictionary containing CGI like environment variables

# which is filled by the server for each received request from the client

environ,

# start_response is a callback function supplied by the server

# which will be used to send the HTTP status and headers to the server

start_response):

# build the response body possibly using the environ dictionary

response_body = 'The request method was %s' % environ['REQUEST_METHOD']

# HTTP response code and message

status = '200 OK'

# These are HTTP headers expected by the client.

# They must be wrapped as a list of tupled pairs:

# [(Header name, Header value)].

response_headers = [('Content-Type', 'text/plain'),

('Content-Length', str(len(response_body)))]

# Send them to the server using the supplied function

start_response(status, response_headers)

# Return the response body.

# Notice it is wrapped in a list although it could be any iterable.

return [response_body]

简单来说就是根据接收的参数来返回相应的结果。

设计web框架

我之前用过django写过一个很简单的博客,目前放在SAE上,好久没更新了。网址:http://3.mrzysv5.sinaapp.com。一个web框架最基本的要求就是简化用户的代码量。所以在django中,我只需要写view、model和url配置文件。下面是我用django时写的一个处理视图的函数:

def blog_list(request):

blogs = Article.objects.all().order_by('-publish_date')

blog_num = Article.objects.count()

return render_to_response('index.html', {"blogs": blogs,"blog_num":blog_num}, context_instance=RequestContext(request))

def blog_detail(request):

bid = request.GET.get('id','')

blog = Article.objects.get(id=bid)

return render_to_response('blog.html',{'blog':blog})

需要我完成的就是操作数据库,返回相应的资源。所以我要编写的web框架就要尽可能的封装一些底层操作,留给用户一些可用的接口。根据我的观察,web框架的处理过程大致如下:

一个WSGI应用的基类初始化时传入配置好的url文件

用户写好处理方法,基类根据url调用方法

返回给客户端视图

一个WSGI基类,主要有以下的功能:

处理environ参数

根据url得到方法或者类名,并执行后返回

import re

class WSGIapp:

headers = []

def __init__(self,urls=()):

self.urls = urls

self.status = '200 OK'

def __call__(self,environ,start_response):

x = self.mapping_urls(environ)

print x

start_response(self.status,self.headers)

if isinstance(x,str):

return iter([x])

else:

return iter(x)

def mapping_urls(self,environ):

path = environ['PATH_INFO']

for pattern,name in self.urls:

m = re.match('^'+pattern+'$',path)

if m:

args = m.groups()

func = globals()[name]

return func(*args)

return self.notfound()

def notfound(self):

self.status = '404 Not Found'

self.headers = [('Content-Type','text/plain')]

return '404 Not Found\n'

@classmethod

def header(cls,name,value):

cls.headers.append((name,value))

def GET_index(*args):

WSGIapp.header('Content-Type','text/plain')

return 'Welcome!\n'

def GET_hello(*args):

WSGIapp.header('Content-Type','text/plain')

return 'Hello %s!\n' % args

urls = [

('/','GET_index'),

('/hello/(.*)','GET_hello')

]

wsgiapp = WSGIapp(urls)

if __name__ == '__main__':

from wsgiref.simple_server import make_server

httpd = make_server('',8000,wsgiapp)

print 'server starting...'

httpd.serve_forever()

上面的代码是不是很简介了,只需要定义函数即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值