标签:调用 body end div lte getattr class 模板 def
学习廖雪峰老师的Python实战教程,在Web框架这部分看了大致一个多礼拜,前面的知识学的不够扎实,由于比较复杂,因此在这里总结下,也算是巩固了。
先看下框架的调用代码:
app = web.Application(loop=loop, middlewares=[logger_factory, response_factory])
init_jinja2(app, filters=dict(datetime=datetime_filter))
add_routes(app, ‘handlers‘)
add_static(app)
response_factory
的代码async def response_factory(app, handler):
async def response(request):
logging.info(‘Response handler...‘)
#获取handler的返回值,根据返回值的不同类型进行处理
r = await handler(request)
print(type(r))
if isinstance(r, web.StreamResponse):
return r
if isinstance(r, bytes):
resp = web.Response(body=r)
resp.content_type = ‘application/octet-stream‘
return resp
if isinstance(r, str):
if r.startswith(‘redirect:‘):
return web.HTTPFound(r[9:])
resp = web.Response(body=r.encode(‘utf-8‘))
resp.content_type = ‘text/html;charset=utf-8‘
return resp
if isinstance(r, dict):
template = r.get(‘__template__‘)
if template is None:
resp = web.Response(body=json.dumps(r, ensure_ascii=False, default=lambda o: o.__dict__).encode(‘utf-8‘))
resp.content_type = ‘application/json;charset=utf-8‘
return resp
else:
resp = web.Response(body=app[‘__templating__‘].get_template(template).render(**r).encode(‘utf-8‘))
resp.content_type = ‘text/html;charset=utf-8‘
return resp
if isinstance(r, int) and r >= 100 and r < 600:
return web.Response(r)
if isinstance(r, tuple) and len(r) == 2:
t, m = r
if isinstance(t, int) and t >= 100 and t < 600:
return web.Response(t, str(m))
# default:
resp = web.Response(body=str(r).encode(‘utf-8‘))
resp.content_type = ‘text/plain;charset=utf-8‘
return resp
return response
add_routes
对‘handlers‘模块的handler进行批量注册def add_route(app, fn):
method = getattr(fn, ‘__method__‘, None)
path = getattr(fn, ‘__route__‘, None)
if path is None or method is None:
raise ValueError(‘@get or @post not defined in %s.‘ % str(fn))
if not asyncio.iscoroutinefunction(fn) and not inspect.isgeneratorfunction(fn):
fn = asyncio.coroutine(fn)
logging.info(‘add route %s %s => %s(%s)‘ % (method, path, fn.__name__, ‘, ‘.join(inspect.signature(fn).parameters.keys())))
app.router.add_route(method, path, RequestHandler(app, fn))
def add_routes(app, module_name):
#找到‘.‘则返回其所在位置,否则返回-1
n = module_name.rfind(‘.‘)
if n == (-1):
#mod为包含module_name模块中全部属性和方法的list
mod = __import__(module_name, globals(), locals())
else:
name = module_name[n+1:]
mod = getattr(__import__(module_name[:n], globals(), locals(), [name]), name)
for attr in dir(mod):
#检查handler是否被@get或@post装饰
if attr.startswith(‘_‘):
continue
fn = getattr(mod, attr)
if callable(fn):
method = getattr(fn, ‘__method__‘, None)
path = getattr(fn, ‘__route__‘, None)
if method and path:
add_route(app, fn)
这里出现了一个RequestHandler类,它具有call魔术方法,所以可以像调用函数一样调用其实例,这里RequestHandler类主要是对handler进行封装,获取request中传入的参数并传入handler中。
最后把我的handler模块的代码贴出来,供参考:
from coroweb import get, post
from aiohttp import web
@get(‘/blog‘)
async def handler_url_blog(request):
body=‘<h1>Awesome: /blog</h1>‘
return body
@get(‘/greeting‘)
async def handler_url_greeting(*,name,request):
body=‘<h1>Awesome: /greeting %s</h1>‘%name
return body
@get(‘/input‘)
async def handler_url_input(request):
body=‘<form action="/result" method="post">E-mail: <input type="email" name="user_email" /><input type="submit" /></form>‘
return body
@post(‘/result‘)
async def handler_url_result(*,user_email,request):
body=‘<h1>您输入的邮箱是%s</h1>‘%user_email
return body
@get(‘/index‘)
async def handler_url_index(request):
body=‘<h1>Awesome: /index</h1>‘
return body
@get(‘/create_comment‘)
async def handler_url_create_comment(request):
body=‘<h1>Awesome: /create_comment</h1>‘
return body
标签:调用 body end div lte getattr class 模板 def
原文地址:https://www.cnblogs.com/vehicle/p/9534464.html