这是应用层第一篇文章,后面的几篇文章也都是和应用层有关的啦
前面我们讲了关于httpserver的内容,httpserver负责网络服务器部分的内容,通过application()函数将data发送到我们的Aapplication里面,这里的application也是一个类 这篇文章主要讲的app.py这个源代码里面的内容.
下面是application类关键部分的代码:
class Application(object):
def __init__(self,handlers):
self.add_handler(handlers)
def __call__(self,req):
self.Request = Request = req
requestrouter = RequestRouter(self.handlers,self.Request)
return requestrouter.execute()
def add_handler(self,host_handler):
self.handlers =[]
for spec in host_handler:
if isinstance(spec, (tuple)):
print spec
spec = URLSpec(*spec)
self.handlers.append(spec)
print self.handlers
if spec.name:
if spec.name in self.named_handlers:
print "Multiple handlers named %s; replacing previous value"%spec.name
self.named_handlers[spec.name]= spec
def get_host_handlers(self):
matches= []
for pattern ,handlers in self.handlers:
matches.extend(handlers)
return matches or None
这个application类是应用层的核心部分,首先解释一下结果函数的作用:
init() 调用add_handler()函数,而这个函数的作用就是用来注册 路由-处理方法
call()这里重写了Python类里面的call函数,在实例化类后,可以直接调用把类当做一个函数调用,application(request)的其实本质上调用的就是这里的call(),我们可以注意到这个call()函数其实非常重要的一个函数, 它是一个请求在应用层的开始.
call()函数一开始实例了一个requestrouter的类,顾名思义,这个类就是包含了路由解析的功能的,一个请求过来,经过路由匹配,成功之后找到对应的处理类,我们定义了每一个处理的类都是继承一个基类BaseReqest()的,匹配成功后会实例对应的处理类,同时执行_excute()方法,执行这个方法的目的是因为:一个处理类用户可以定义很多种方法,而使用_execute()方法可以根据请求的method来执行对应的处理函数.整个应用层路由解析部分的内容大致就是这样的.
下面来看下前面提到的requestrouter类和baserequest的代码:
class RequestRouter(object):
def __init__(self,handlers,request):
self.handlers =handlers
self.request = request
self.handler_class = None
self.handler_kwargs = {}
self.path_args = []
self.path_kwargs = {}
print self.request.path()
self.find_handler()
def find_handler(self):
handlers = self.handlers
if not handlers:
self.handlers_class = RedirectHandler
#self.handler_kwargs = {}
return
for spec in handlers:
match = spec.regex.match(self.request.path())
print self.request.path()
print match
if match !=None:
print spec
self.handler_class = spec.handler_class
self.handler_kwargs = spec.kwargs
if spec.regex.groups:
if spec.regex.groupindex:
self.path_kwargs = dict(
(str(k), _unquote_or_none(v))
for (k,v) in match.groupdict().item())
else:
self.path_kwargs = [_unquote_or_none(s)
for s in match.groups()]
return
def execute(self):
if self.handler_class !=None:
self.handler = self.handler_class(self.request,**self.handler_kwargs)
return self.handler._excute(*self.path_args,**self.path_kwargs)
else:
print 'app 149 '
error = HttpError('404 ','not foound you request page ')
return error()
class BaseRequest(object):
Default_Method = ["GET","POST", "DELETE","PUT"]
def __init__(self,request,**kwargs):
super(BaseRequest, self).__init__()
self.request = request
self.status_code ='200 OK'
self.header = []
def _excute(self,*args,**kwargs):
print 'steart _execute'
try:
print self.request.method
if self.request.method() not in self.Default_Method:
error= HttpError('405 Method Not Allowed','Invalid method')
return error()
self.path_args = [self.decode_argument(arg) for arg in args]
self.path_kwargs = dict((k, self.decode_argument(v, name=k))
for (k, v) in kwargs.items())
method = getattr(self,self.request.method().lower())
print 'get method ...........'
result = method (*self.path_args,**self.path_kwargs)
print 'this is result ------.'
print result
if result is not None:
return result
except Exception as e:
error= HttpError('500 Internal Server Error','some error in server ')
print 'Exception in handler excute'
return error()
def decode_argument(self, value, name=None):
try:
return to_unicode(value)
except UnicodeDecodeError:
error = HttpError('400 Bad Request', "Invalid unicode in %s: %r" %
(name or "url", value[:40]))
return error()
def set_status_code(self,code):
self.status_code = code
def set_header(self,key,value):
self.header.append((key,value))
def set_cookie(self,value):
self.header.append(('Cookie',value))
def Response(self,result):
results = (self.status_code,self.header,result)
return results
看完了这个两个类的代码再来重新看一下掌心宝似的call()函数
def __call__(self,req):
self.Request = Request = req
requestrouter = RequestRouter(self.handlers,self.Request)
return requestrouter.execute()
可以看出requestrouter类和baserequest这两个类基本都是为这个call()函数服务的.
同时也看到baserequest这个类封装了一些基本的方法,set_header,set_cookie()等,后面会根据需求进行扩展. Response()这个函数是用来返回处理结果的.也可以重新写过增加框架的灵活性.对app.py代码的介绍差不多就这样了,app.py里面里的工具类可能比较多(其实是我懒没有写多少)就不一一把代码贴出来了,那样子意义不大.
下一篇主要讲一下,我们这个平台的main.py代码,一看就知道是干嘛用的啦,这个当然使我们启动的整个平台的入口程序
All rights reserved.