博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python中Web框架编写学习心得
阅读量:4983 次
发布时间:2019-06-12

本文共 3856 字,大约阅读时间需要 12 分钟。

学习廖雪峰老师的,在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)
  1. 使用web.Application类创建aiohttp server——app,其中loop为Eventloop用来处理HTTP请求,middlewares为中间件,在这里用来记录日志并处理handler返回的数据为web.response对象,这里看下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
  1. 使用jinjia2模板来构建前端页面,这里我们暂时没有用到
  2. 注册处理url的handler,aiohttp中的add_route函数进行注册,我们这里使用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中。

  1. add_static是用户处理如图片、js、css等静态资源的,仅供开发环境中方便使用,生产环境一般使用nginx或CDN之类的,这块我也还没有搞清楚,没办法梳理

最后把我的handler模块的代码贴出来,供参考:

from coroweb import get, postfrom aiohttp import web @get('/blog') async def handler_url_blog(request): body='

Awesome: /blog

' return body @get('/greeting') async def handler_url_greeting(*,name,request): body='

Awesome: /greeting %s

'%name return body @get('/input') async def handler_url_input(request): body='
E-mail:
' return body @post('/result') async def handler_url_result(*,user_email,request): body='

您输入的邮箱是%s

'%user_email return body @get('/index') async def handler_url_index(request): body='

Awesome: /index

' return body @get('/create_comment') async def handler_url_create_comment(request): body='

Awesome: /create_comment

' return body
作者:糊君
链接:https://www.jianshu.com/p/0fded26001e3
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

转载于:https://www.cnblogs.com/vehicle/p/9534464.html

你可能感兴趣的文章
Python---Flask--02--模板
查看>>
PHP学习笔记---封装(面向对象三大特性之一)
查看>>
如何快速找到指定端口被哪个程序占用并释放该端口(解决bindException)
查看>>
迭代之while循环(1)
查看>>
final修饰的类有什么特点
查看>>
关于string类中find函数的讲解
查看>>
程序员的情书
查看>>
Spring Cloud Eureka 使用 IP 地址进行服务注册
查看>>
Python 包的制作(__init__.py)
查看>>
java内存模型优化建议
查看>>
三十、模块补充
查看>>
流程审批设计
查看>>
别装了,你根本就不想变成更好的人
查看>>
数据库 join
查看>>
AES加密工具类[亲测可用]
查看>>
方法区
查看>>
Django-----ORM
查看>>
ARCGIS部分刷新
查看>>
发 零 食
查看>>
poj3613:Cow Relays(倍增优化+矩阵乘法floyd+快速幂)
查看>>