Web框架

Web应用框架(Web application framework)是一种开发框架,用来支持动态网站、网络应用程序及网络服务的开发。Web应用框架有助于减轻网页开发时共通性活动的工作负荷,例如许多框架提供数据库访问接口、标准样板以及会话管理等,可提升代码的可再用性。

Python web框架比较

下面对常见的三种Python web框架进行简单的介绍:

Django

Django已经成为Python最广泛部署的用于创建Web应用程序的框架之一。 Django配备了可能需要的大部分组件,因此它倾向于构建大型应用程序而不是小型应用程序。
Django的socket用的是wsgiref模块,路由与视图函数、模板渲染都是自己的写的。

Flask

关于Python中的Web框架的大多数讨论都是从Flask开始提到的。 Flask是一个成熟的,易于理解的框架,广泛使用且非常稳定,短小精悍,自带的功能模块特别少,大部分都是依赖于第三方模块。
Flask的socket用的是wsgiref模块,路由与视图函数是自己的写的,模板渲染用的是第三方模块jinjia2。

Tornado

Tornado是针对特定用例的另一个小框架,天生异步,性能强悍。Tornado专为构建异步网络应用程序而设计,非常适合创建同时打开大量网络连接并使其保持活动状态的服务,即涉及WebSockets或长轮询的任何内容。
socket、路由与视图函数、模板渲染都是自己的。

Web框架本质

Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。 这样我们就可以按照HTTP协议来实现一个简单版的Web框架了。

import socket
server = socket.socket()  # 不传参数默认就是TCP协议
server.bind(('127.0.0.1',8080)) # 绑定IP和端口
server.listen(5)while True:conn, addr = server.accept()  # 阻塞 等待客户端链接data = conn.recv(1024)# 因为要遵循HTTP协议,所以回复的消息也要加状态行conn.send(b'HTTP/1.1 200 OK\r\n\r\n')# 手动处理http数据获取用户访问的路径,url是我们从浏览器发过来的消息中分离出的访问路径current_path = data.decode('utf-8').split('\r\n')[0].split(' ')[1]if current_path == '/index':# 路由匹配上之后返回index# conn.send(b'<h1>index</h1>')with open('index.html','rb') as f:# TCP对于发送间隔时间较短和较少的内容会一次发送过去conn.send(f.read())else:# 当匹配不上的时候统一返回404conn.send(b'404 not found!')conn.close()

这网页能够显示出来了,但是都是静态的啊。页面的内容都不会变化的,我想要的是动态网站。

import socket
import time
sk = socket.socket()
sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口
sk.listen(5)  # 监听
# 将返回不同的内容部分封装成函数
def index(url):with open("index.html", "r", encoding="utf8") as f:s = f.read()now = time.strftime('%Y-%m-%d %X')res = s.replace("@@time@@", now)  # 在网页中定义好特殊符号,用动态的数据去替换提前定义好的特殊符号return res
def home(url):with open("home.html", "r", encoding="utf8") as f:res = f.read()return res
# 定义一个url和实际要执行的函数的对应关系
list1 = [("/index", index),("/home", home),
]
while True:# 等待连接conn, add = sk.accept()data = conn.recv(8096)  # 接收客户端发来的消息# 从data中取到路径data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串# 按\r\n分割data1 = data.split("\r\n")[0]url = data1.split(" ")[1]  # url是我们从浏览器发过来的消息中分离出的访问路径conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行# 根据不同的路径返回不同内容func = None  # 定义一个保存将要执行的函数名的变量for i in list1:if i[0] == url:func = i[1]breakif func:response = func(url)else:response = "404 not found!"# 返回具体的响应消息conn.send(response.encode('utf-8'))conn.close()

WSGI

PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI)是Python应用程序或框架和Web服务器之间的一种接口,已经被广泛接受, 它已基本达成它的可移植性方面的目标。WSGI 没有官方的实现, 因为WSGI更像一个协议. 只要遵照这些协议,WSGI应用(Application)都可以在任何服务器(Server)上运行。

wsgiref模块

最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,都由自己来实现很浪费时间和精力。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口协议来实现这样的服务器软件,让我们专心用Python编写Web业务。这个接口就是WSGI:Web Server Gateway Interface。而wsgiref模块就是python基于wsgi协议开发的服务模块。

我们利用wsgiref模块来替换我们自己写的web框架的socket server部分:

from wsgiref.simple_server import make_server
import timedef index(env):with open("index.html", "r", encoding="utf8") as f:s = f.read()now = time.strftime('%Y-%m-%d %X')res = s.replace("@@time@@", now)  # 在网页中定义好特殊符号,用动态的数据去替换提前定义好的特殊符号return res
def home(env):with open("home.html", "r", encoding="utf8") as f:res = f.read()return resdef error(env):return '404 error'urls = [('/index',index),('/home',home),
]def run(env,response):''':param env:请求相关的信息:param response:响应相关的信息:return:'''response('200 OK',[('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息# env是一个大字典 里面装了一堆处理好了的键值对数据url = env.get('PATH_INFO') # 取到用户输入的urlfunc = Nonefor url_map in urls:if url == url_map[0]:func = url_map[1]breakif func:res = func(env)else:res = error(env)return [res.encode('utf-8')]if __name__ == '__main__':server = make_server('127.0.0.1',8080,run)server.serve_forever()

jinja2

上面的代码实现了一个简单的动态,我完全可以从数据库中查询数据,然后去替换我html中的对应内容,然后再发送给浏览器完成渲染。 这个过程就相当于HTML模板渲染数据。 本质上就是HTML内容中利用一些特殊的符号来替换要展示的数据。其实模板渲染有个现成的工具: jinja2

jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用。jinja2模块中有一个名为Enviroment的类,这个类的实例用于存储配置和全局对象,然后从文件系统或其他位置中加载模板。

jinja2之所以被广泛使用是因为它具有以下优点:

  1. 相对于Template,jinja2更加灵活,它提供了控制结构,表达式和继承等。
  2. 相对于Mako,jinja2仅有控制结构,不允许在模板中编写太多的业务逻辑。
  3. 相对于Django模板,jinja2性能更好。
  4. Jinja2模板的可读性很棒。

安装

由于jinja2属于第三方模块,首先需要对其进行安装

pip3 install jinja2

使用jinja2渲染html文件:

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script><link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"><script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container"><div class="row"><div class="col-md-8 col-md-offset-2"><table class="table table-hover table-striped table-bordered"><thead><tr><th>id</th><th>name</th><th>password</th></tr></thead><tbody>{% for user in user_dict %}  <!--[{},{},{},{}]--><tr><td>{{ user.id }}</td><td>{{ user.name }}</td><td>{{ user.password }}</td></tr>{% endfor %}</tbody></table></div></div>
</div>
</body>

py代码

from wsgiref.simple_server import make_server
from jinja2 import Template
import pymysqldef index(env):# 连接数据库 获取数据 渲染到前端页面conn = pymysql.connect(host = '127.0.0.1',port = 3306,user = 'root',password = 'mysql',database = 'jinja',charset = 'utf8',autocommit = True)cursor = conn.cursor(pymysql.cursors.DictCursor)cursor.execute('select * from userifo')user_dict= cursor.fetchall()  # [{},{},{},{}]with open(r'templates/index.html','r',encoding='utf-8') as f:data = f.read()tmp = Template(data)return tmp.render(user_dict=user_dict)def error(env):return '404 error'urls = [('/index',index),
]def run(env,response):''':param env:请求相关的信息:param response:响应相关的信息:return:'''response('200 OK',[('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息# env是一个大字典 里面装了一堆处理好了的键值对数据url = env.get('PATH_INFO') # 取到用户输入的urlfunc = Nonefor url_map in urls:if url == url_map[0]:func = url_map[1]breakif func:res = func(env)else:res = error(env)return [res.encode('utf-8')]if __name__ == '__main__':server = make_server('127.0.0.1',8080,run)server.serve_forever()

手写简易版web框架相关推荐

  1. 解鞍卸甲——手写简易版Spring框架(终):使用三级缓存解决循环依赖问题

    什么是三级缓存 按照目前我们实现的 Spring 框架,是可以满足一个基本需求的,但如果你配置了A.B两个Bean对象互相依赖,那么立马会抛出 java.lang.StackOverflowError ...

  2. 手写简易版Spring框架(七):定义标记类型接口Aware,实现感知容器相关的信息

    文末有惊喜 目标 目前已实现的 Spring 框架,在 Bean 操作上能提供出的能力,包括:Bean 对象的定义和注册,以及在操作 Bean 对象过程中执行的,BeanFactoryPostProc ...

  3. 手写简易版链表及原理分析

    好多人都觉得为什么要自己写这样的数据结构,变成里面不是有吗?为什么要去写,有这个疑问,其实这个疑问这我的脑海中也存在了很长一段时间,本人是学习java编程的,直接看java的集合框架不行吗?这个时候如 ...

  4. 5 拦截器拦截请求路由_手写简易版axios拦截器,实现微信小程序wx.request的封装与拦截...

    前言: axios是一个功能强大的网络请求库,其中拦截器又是axios的精髓.在小程序的开发或者需要手动实现ajax的时候,没有实现对请求的拦截,开发的时候非常不方便,因此手写一个简易版的axios拦 ...

  5. 手写简易版 React 来彻底搞懂 fiber 架构

    React 16 之前和之后最大的区别就是 16 引入了 fiber,又基于 fiber 实现了 hooks.整天都提 fiber,那 fiber 到底是啥?它和 vdom 是什么关系? 与其看各种解 ...

  6. 手写简易版Vue源码之数据响应化的实现

    当前,Vue和React已成为两大炙手可热的前端框架,这两个框架都算是业内一些最佳实践的集合体.其中,Vue最大的亮点和特色就是数据响应化,而React的特点则是单向数据流与jsx. 笔者近期正在研究 ...

  7. Dubbo——手写简单版Dubbo框架

    摘要 本博文将详细的介绍的一个手写简单版本的dubbo的实现. 项目架构原理图 项目源码实现 https://github.com/2462612540/DubboPrinciple/tree/mas ...

  8. 彻底搞懂fiber架构, 手写简易版 React

    vdom: 16v 前: vdome -> 递归 diff render; 递归渲染时做 diff 来确定增删改以及创建 dom 通过children关联父子节点 递归diff 不可中断 影响性 ...

  9. java hash简易_Java手写简易版HashMap的使用(存储+查找)

    hashmap的基本结构 package com.liuyuhe; public class node { int hash; object key; object value; node next; ...

最新文章

  1. Cookie注入是怎样产生的
  2. HR吐槽BAT员工:不要把平台的光环当成自己的,我们需要造火箭的。
  3. Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
  4. java 右键卡死_为什么右键单击不适用于Java应用程序?
  5. 低格硬盘用什么软件_迟来的评测:用了三年后的固态硬盘会变成什么样呢?
  6. mac下解决中文乱码的问题
  7. 流行的Spring Boot + Vue架构整合开发的网易云+QQ音乐(附源码)!
  8. 热部署Devtools
  9. Render Monkey中可渲染纹理的Clear Color
  10. sklearn机器学习之分类预测算法应用
  11. mysql innodb_data_file_path_应急预案:专有云V3环境中RDS MySQL5.7实例修改innodb_temp_data_file_path参数的方法...
  12. 如何理解泊松分布(Poisson Distribution)
  13. python电路仿真软件_4种电路仿真软件比较 - SmartLinkCloud,智联网云平台 - OSCHINA - 中文开源技术交流社区...
  14. [转]C#中的global关键字(global::)
  15. python查询ip归属地_基于Python的免费IP地址归属地查询
  16. tp5.1 乐视云上传视频文件(https请求http乐视云上传接口)http网址下上传视频(https API接口)
  17. IDEA导入主题皮肤
  18. 2022-2028全球与中国化学机械抛光(CMP金刚石衬垫调节器市场现状及未来发展趋势
  19. 用java程序连接虚拟机中的SequoiaDB-Mysql实例
  20. 广州网络营销师吴家成教你网站网页标题title优化设置

热门文章

  1. pstree命令使用
  2. 学计算机要Ghz,ghz是什么意思,电脑ghz是什么意思?
  3. SP申请业务方案编写模板
  4. 中国Linux与微软斗法北京谋变,从水火不容到共生(转)
  5. 使用spotify的docker-maven-plugin插件将SpringBoot项目打包为Docker镜像
  6. webstorm背景颜色修改为护眼豆沙绿
  7. Java篇第七回——内部类与异常类
  8. AST反混淆插件|如何还原Array对象里的元素
  9. 完美世界2018年净利润17亿元 同比增长13.16%
  10. 调优四剑客的实战演练,福尔摩斯•K带你轻松优化性能