Day 5 - 编写Web框架 代码优化

简介:

1.匿名sina网友V 

廖大的版本

def add_routes(app, module_name):

    n = module_name.rfind('.')

    if n == (-1):

        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):

        if attr.startswith('_'):

            continue

        fn = getattr(mod, attr)

        if callable(fn):

        #这里用callable区分函数和普通成员变量是不合适地。

        #总是有一些奇怪的东西混进来,例如handler里边引入的User 用callable判断它总是True,然而扫描User纯粹是浪费电。

            method = getattr(fn, '__method__', None)

            path = getattr(fn, '__route__', None)

            if method and path:

            #这里method和path 判断完就丢了,有点可惜,add_route()里边还要再费二遍事,最好能修改add_route的签名,add_route(app,fn,method,path)一套传过去。

                add_route(app, fn)



我改过的

import types

def add_routes(app,module_name):

    n = module_name.rfind('.')

    if n == (-1):

        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):

        if attr.startswith('_'):

            continue

        fn = getattr(mod , attr)

        if isinstance(fn,types.FunctionType):

            has_method = hasattr(fn,"__method__")

            has_path = hasattr(fn,"__route__")

            if has_method and has_path:

                add_route(app,fn)




2.middleware和RequestHandler是一定要实现的,不然耦合度太高很容易混乱。

相反,add_route可以省略,如果只加一个的话app.router.add_route就足以应付了。


这是我重构过的版本, __import__有一个黑魔法,不用写得这么复杂的:


mod = __import__(module_name, fromlist=[''])


叫做mblog-master

github地址 https://github.com/moling3650/mblog


3.你的add_routes()很机智,廖大版的method 和 path 查到了不用实在是浪费。

RequestHandler看起来写得和廖大的结构上不一样,粗略的搂了两眼,两份我都没仔细看具体实现。


在这里我得黑一下廖大,廖大版的RequestHandler 貌似把handler函数的参数名写死了,handler的参数必须得叫request。我感觉这样对用户不太友好,这是对用户赤裸裸地强J。

最好能用判断类型的方法来代替判断参数名的方法,来保证传入了一个request类型的参数。这样用户写handler的时候就r,req,request 什么的随意写了。用户用得爽了,框架才有市场。


4.https://github.com/moling3650/mblog

效果图

http://www.qiangtaoli.com/bootstrap/manage/blogs

我的已经是做完了,而且重构了不少地方,比如RequestHandler,重构的理由在这里。


你黑的并不是地方,不是handler函数的参数写死了,而是app.router.add_route方法的第三个参数写死了,这里必需是一个只有一个参数request的函数,所以才用__call__统一封装成RequestHandler(handler)(request)的形式,这样使得handler的参数可以多样化。


然而RequestHandler是整个项目中最值得黑的地方,你可以看看我和别人在楼下的评论就会知道真正值得黑的地方在哪里了XD


5.add_routes最后直接用一个if更简洁

if isinstance(fn, types.FunctionType) and hasattr(fn, '__method__') and hasattr(fn, '__route__'):

    add_route(app, fn)


6.你没读过asyncio的源码才会这样说,func = asyncio.coroutine(func)这方法会内部处理func是协程或生成器,根本无需在外先判断func的类型,最终出来的就是标准的协程函数。


在add_routes都用了method = getattr(func, '__method__', None)了,还要在add_route进行hasattr(fn, '__method__')判断是没有意义的,在add_routes中没有__method__和__route__属性时根本不会调用add_route


add_route这些判断是为单独调用时存在的,然而并没有单独调用的场景。有单独调用的场景我倒不如直接用pp.router.add_route了。


7.看明白了,你只需要简单判断一下callable就可以丢给add_route处理就行了,hasattr(fn, '__method__') and hasattr(fn, '__route__')放在add_route处理就好。


8.async def logger_factory(app, handler): #这就是个装饰器呀

    async def logger(request):

        logging.info('Request: %s %s Begin>>>' % (request.method, request.path))

        # await asyncio.sleep(0.3)

        rst = (await handler(request))

        return rst

    return logger


async def response_factory(app, handler): #这个middleware比较不错,大家在handler里边可以返回各种类型的结果,在这里统一由廖大的response_factory给大家擦屁股。

    。。。


middleware的代码示意:

m1( m2( m3( doFoo())))


middleware调用流程:

req -> m1 -> m2 -> m3 -> doFoo()- 一路return 原路返回

<- m1 <- m2 <- m2 <- resq - <-



本文转自 liqius 51CTO博客,原文链接:http://blog.51cto.com/szgb17/1943522,如需转载请自行联系原作者

相关文章
|
1月前
|
安全 数据库 开发者
Python Web框架简介
【2月更文挑战第10天】Python Web框架简介。
90 2
|
10天前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
【4月更文挑战第9天】本文对比了Python三大Web框架Django、Flask和Pyramid。Django功能全面,适合快速开发,但学习曲线较陡;Flask轻量灵活,易于入门,但默认配置简单,需自行添加功能;Pyramid兼顾灵活性和可扩展性,适合不同规模项目,但社区及资源相对较少。选择框架应考虑项目需求和开发者偏好。
|
4天前
|
前端开发 数据挖掘 API
使用Python中的Flask框架进行Web应用开发
【4月更文挑战第15天】在Python的Web开发领域,Flask是一个备受欢迎的轻量级Web框架。它简洁、灵活且易于扩展,使得开发者能够快速地构建出高质量的Web应用。本文将深入探讨Flask框架的核心特性、使用方法以及在实际开发中的应用。
|
16天前
|
前端开发 安全 Java
使用Java Web框架:Spring MVC的全面指南
【4月更文挑战第3天】Spring MVC是Spring框架的一部分,用于构建高效、模块化的Web应用。它基于MVC模式,支持多种视图技术。核心概念包括DispatcherServlet(前端控制器)、HandlerMapping(请求映射)、Controller(处理请求)、ViewResolver(视图解析)和ModelAndView(模型和视图容器)。开发流程涉及配置DispatcherServlet、定义Controller、创建View、处理数据、绑定模型和异常处理。
使用Java Web框架:Spring MVC的全面指南
|
30天前
|
数据库
最全三大框架整合(使用映射)——struts.xml和web.xml配置
最全三大框架整合(使用映射)——数据库资源文件jdbc.properties
9 0
|
1月前
|
前端开发 API 网络架构
Python 如何开发出RESTful Web接口,DRF框架助力灵活实现!
Python 如何开发出RESTful Web接口,DRF框架助力灵活实现!
|
1月前
|
XML JSON API
通过Flask框架创建灵活的、可扩展的Web Restful API服务
通过Flask框架创建灵活的、可扩展的Web Restful API服务
|
1月前
|
物联网 调度 开发者
构建高效Python Web应用:异步编程与Tornado框架解析
【2月更文挑战第27天】 在处理高并发的Web应用场景时,传统的同步阻塞模型往往难以满足性能需求。本文将深入探讨Python世界中的异步编程概念,并结合Tornado这一轻量级、非阻塞式Web服务器及框架,展示如何构建高性能的Web应用。通过实例驱动的方法论,我们将剖析Tornado的核心组件,包括其IOLoop、异步HTTP客户端和服务器端处理机制,以及与协程集成的细节。文章旨在为开发者提供一套实践指南,帮助他们利用Python实现快速响应和资源高效的Web服务。
28 2
|
1月前
|
设计模式 前端开发 API
简述 Python WEB 开发常用的框架有哪些?
【2月更文挑战第26天】【2月更文挑战第88篇】简述 Python WEB 开发常用的框架有哪些?
|
1月前
|
设计模式 前端开发 数据库
Django是一个用Python编写的开源Web应用框架
Django是一个用Python编写的开源Web应用框架
12 1

热门文章

最新文章