知识回顾

1、django 和flask区别?

  最大的不同就是django请求相关的数据,通过参数一个一个传递过去的,而flask就是先把放在某个地方,然后去取,这个东西叫上下文管理

2、什么是wsgi?

  web服务网关接口,wsgi就是一个协议和规范,实现该协议的模块:

  -wsgiref

  -werkzeug

  实现其协议的模块本质上就是socket服务端用于接收用户请求,并处理,

  一般web框架基于wsgi实现,这样实现关注点分离(通俗的说业务相关的,交给框架)

from werkzeug.wrappers import  Response
from werkzeug.serving import run_simple def run_sever(environ,start_response):
response=Response('duoduo') # 封装一下
return response(environ,start_response) if __name__ == '__main__':
run_simple('127.0.0.1',8000,run_sever)

3、flask提供的功能

配置文件

  所有配置文件都在flask的对象.config中

  flask的对象.config.from_object('引入类的路径')   小写也是生效的

  应用: importlib 、getattr

    django中间件

    rest framework全局配置

session

  加密后放置在用户浏览器的cookie中

  流程:

    请求到来--------》视图函数---------》请求结束

  配置文件   生命周期31天   加密设置

路由

  带参数的装饰器,自定义装饰器放下面

  常用url,methods,endpoint   反向 url_for

视图

  FBV

特殊装饰器

  before_first_request

  before_request

  after_request

  template_global()

  template_filter()

  errorhandler(404)

请求和响应

  请求:request

  响应:四种 字符串、render_template(模板)、redirect、jsonify (序列化)

  加响应头就make_response

一、路由和视图

from flask import Flask
duo=Flask(__name__) @duo.route('/index')
def index():
print('index')
return 'Index' if __name__ == '__main__':
duo.run()

我们今天开看看route的源码是什么样子的:

先不看中间的,发现定义阶段只是返回了 函数decorator的名字

1、限制性  decorator=duo.route('/index')

2、@decorator   这就和装饰器的原理一样,执行的话就把被装饰的函数名字传进去

3、上图中的f就是index函数,而rule就是(’/index‘)

这里就可以看出这个装饰器实质上就是:

duo.add_url_rule('/index', None, index)

我们注释掉装饰器,就用这一句代码跑跑看,脚本跑起来没问题!

我们继续看。add_url_rule里面的源码:

验证了之前说过的为什么endpoint默认情况等于函数名

获得参数都放到类似一个类,点开看看

果然是一个类

将路有关系添加到所有路由关系映射表

总结:

尽量不要让endpoint重名,如果重名函数一定要相同

参数:

rule,                       URL规则
view_func, 视图函数名称
defaults=None, 默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
endpoint=None, 名称,用于反向生成URL,即: url_for('名称')
methods=None, 允许的请求方式,如:["GET","POST"]
strict_slashes=None, 对URL最后的 / 符号是否严格要求,
@app.route('/index',strict_slashes=False),
访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可
@app.route('/index',strict_slashes=True)
仅访问 http://www.xx.com/index
redirect_to=None, 重定向到指定地址
@app.route('/index/<int:nid>', redirect_to='/home/<nid>')

def func(adapter, nid):
return "/home/888"
@app.route('/index/<int:nid>', redirect_to=func)
subdomain=None, 子域名访问

CBV:

from flask import Flask,views
import functools
def wrapper(func):
@functools.wraps(func)
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner duo=Flask(__name__) class UserView(views.MethodView):
methods = ['GET'] #只允许GET请求
decorators = [wrapper,] #加上要执行的装饰器的名字
def get(self,*args,**kwargs): return 'GET' def post(self,*args,**kwargs):
return 'POST' duo.add_url_rule('/user',None,UserView.as_view('uuuu')) if __name__ == '__main__':
duo.run()

基本上大同小异

自定义正则:

from  flask import Flask,url_for
duo=Flask(__name__) #步骤一:定制类
from werkzeug.routing import BaseConverter class RegexConverter(BaseConverter):
'''
自定义URL匹配正则表达式
'''
def __init__(self,map,regex):
super(RegexConverter,self).__init__(map)
self.regex=regex def to_python(self, value):
'''
路由匹配时,匹配成功过后传递给视图函数中参数的值
:param value:
:return:
'''
return int(value) def to_url(self, value):
'''
使用url_for反向生成URL时,传递的参数经过该方法处理,返回值用于生成URL中的参数
:param value:
:return:
'''
val=super(RegexConverter,self).to_url(value)
return val #完全可以不写 #步骤二:添加到转换器
duo.url_map.converters['reg']=RegexConverter '''
1、用户发送请求
2、flask内部进行正则匹配
3、调用to_python(正则匹配的结果)方法
4、to_python的返回值会交给视图函数的参数''' #步骤三:使用自定义正则
@duo.route('/index/<reg("\d+"):nid>')
def index(nid):
print(nid,type(nid))
print(url_for('index',nid=1))
return 'index' if __name__ == '__main__':
duo.run()

二、session实现原理(源码)

flask

下面我们来一行行来验证上面猜想的:

self 是Flask的对象duo,environ请求相关的原始数据

三、蓝图

目标:给开发者提供一个目录结构

1、首先创建一个和项目一样名字的文件夹,在文件夹中的__init__.py,先定义一个创建对象的函数

from flask import Flask

def create_app():
duo=Flask(__name__)
return duo

2、在项目一样名字的文件夹下,创建视图文件夹,在里面单独创建需求的功能视图

from flask import Blueprint

uc=Blueprint('ac',__name__)
@uc.route('/index/')
def index():
return 'Index'

3、建立他们之间的关系,在__init__导入生成的对象 uc,最后注册进去

from flask import Flask
from .views.user import uc def create_app():
duo=Flask(__name__)
duo.register_blueprint(uc,url_prefix='/duoduuo') #url_prefix适用版本控制
return duo #最后再写一个运行的脚本,

其他的功能:

自定义模板、静态文件

某一类url添加前缀

某一类url添加before_request

四、threading.local(和flask无任何关系)

先看一个简单事例:

import threading
import time
v=0
def task(i):
global v
v=i
time.sleep(1)
print(v) for i in range(10):
t=threading.Thread(target=task,args=(i,))
t.start() #结果都是9,最后一个修改覆盖所有,解决方法加锁

看一种解决方案:

import threading
from threading import local
#为每给线程创建一个独立空间来修改数据,使得线程对自己的空间中的数据进行操作(数据隔离)
import time obj=local() def task(i):
obj.duo=i
time.sleep(1)
print(obj.duo,i) for i in range(10):
t=threading.Thread(target=task,args=(i,))
t.start()

现在我们来考虑几个问题,

如何获取一个线程的唯一标记 ?

threading.get_ident()  #跟linux进程pid类似

根据字典自定义一个类似于threading.local功能?

通过getattr,setattr 构建出加强版的threading.local功能!

import  time
import threading
try:
import greenlet #有就是协程,没有就是线程
get_ident=greenlet.getcurrent
except Exception as e:
get_ident=threading.get_ident
class Local(object):
DIC={}
def __getattr__(self, item): #self.xxx 触发执行
# print('getattr',item)
ident=get_ident()
if ident in self.DIC:
return self.DIC[ident].get(item)
return None def __setattr__(self, key, value): #self.xxx=123 触发执行
# print('setattr',key,value)
ident=get_ident()
if ident in self.DIC:
self.DIC[ident][key]=value
else:
self.DIC[ident]={key:value}
obj=Local()
def task(i):
obj.duo=i
time.sleep(1)
print(obj.duo,i) for i in range(10):
t=threading.Thread(target=task,args=(i,))
t.start()

后续还是有看源码的博客:

五、简述上下文管理

1、当请求到来时,在源码中wsgi_app 中 ctx 对象是RequestContext封装所有的对象和请求相关的原始数据,

这个对象就有request和session,在接下来的对session进行补充,将包含了request/session的ctx对象放到’神奇的地方‘

这个神奇的地方就是一个大字典,用线程或协程的唯一标识为key,

2、当视图函数使用的时候:

假使取一个request.method  ,我们先导入 from  flask import request ,根据当前线程取ctx对象,再取request,再取.method

3、当请求结束:

根据当前线程的唯一标记,将’神奇地方‘上的数据移除

python3-开发进阶Flask的基础(2)的更多相关文章

  1. python3开发进阶-Web框架的前奏

    我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端. 这样我们就可以自己实现Web框架了. 1.自定义web框架 import socket ...

  2. python3-开发进阶Flask的基础(5)

    内容概要: SQLAlchemy flsak-sqlalchemy flask-script flask-migrate Flask的目录结构 一.SQLAlchemy 1.概述 SQLAlchemy ...

  3. python3-开发进阶Flask的基础

    一.概述 最大的特点:短小精悍.可拓展强的一个Web框架.注意点:上下文管理机制,依赖wsgi:werkzurg 模块 二.前奏学习werkzurg 先来回顾一个知识点:一个类加括号会执行__init ...

  4. python3开发进阶-Django框架的起飞加速一(ORM)

    阅读目录 ORM介绍 Django中的ORM ORM中的Model ORM的操作 一.ORM介绍 1.ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一 ...

  5. python3开发进阶-Django框架起飞前的准备

    阅读目录 安装 创建项目 运行 文件配置的说明 三个组件 一.安装(安装最新LTS版) Django官网下载页面 根据官方的图版本,我们下载1.11版本的,最好用! 有两种下载方式一种直接cmd里: ...

  6. python3-开发进阶Flask的基础(4)

    今日内容: 上下文管理:LocalProxy对象 上下文管理:  请求上下文: request/session   app上下文:app/g 第三方组件:wtforms       1.使用      ...

  7. python3-开发进阶Flask的基础(3)

    上篇我们大概简单描述了一下上下文管理,这篇来具体来说说, 上下管理的request 上下管理的session 第三方组件:flask-session pymysql操作数据库  数据库连接池 一.前奏 ...

  8. python3开发进阶-Django框架的自带认证功能auth模块和User对象的基本操作

    阅读目录 auth模块 User对象 认证进阶 一.auth模块 from django.contrib import auth django.contrib.auth中提供了许多方法,这里主要介绍其 ...

  9. python3开发进阶-Django框架的Form表单系统和基本操作

    阅读目录 什么是Form组件 常用字段和插件 自定义校验的方式 补充进阶 一.什么是Form组件 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标 ...

随机推荐

  1. HDU 1214 圆桌会议 (找规律)

    题目链接 Problem Description HDU ACM集训队的队员在暑假集训时经常要讨论自己在做题中遇到的问题.每当面临自己解决不了的问题时,他们就会围坐在一张圆形的桌子旁进行交流,经过大家 ...

  2. perl6 Socket

    Perl6 中的SOCKET就是相当于Perl5 的 IO::Socket::INET. 官方介绍如下: #下面是客户端multi method new( :$host, :$port, :, :$e ...

  3. SQLite3 安装、基本操作

    1. 安装SQLite3 sudo apt-get install sqlite3 2. 安装Sqlite3编译需要的工具包 如果,你需要的话可以安装该工具包.只是为了体验一把,可以不安装.该项是可选 ...

  4. NoSQL-来自维基百科

    NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称. 两者存在许多显著的不同点,其中最重要的是NoSQL不使用SQL作为查询语言.其数据存储可以不需 ...

  5. 64_r3

    rubygem-resque-cleaner-0.3.0-5.fc24.noarch.rpm 24-Sep-2016 22:26 22422 rubygem-resque-cleaner-doc-0. ...

  6. 分布式队列Celery入门

    Celery 是一个简单.灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具.它是一个专注于实时处理的任务队列,同时也支持任务调度.Celery 是语言无关的,虽然它是用 Py ...

  7. oracle中的符号含义

    1.Oracle数据库存储过程中:=是什么意思?答:赋值的意思.举例:str := 'abcd';将字符串abcd赋值给变量str. 2.oracle 存储过程中的 := 和=有什么区别?答::= 是 ...

  8. Web服务器处理动态程序三种方式及Apache配置

    模块.CGI.FastCGI三种方式介绍 以PHP脚本为例: 模块方式是指Web服务器通过libphp5.so模块调用PHP服务,模块将相关函数嵌入Web服务请求处理流程,不需要额外解释器进程.注意, ...

  9. 提高spring boot jpa性能(译)

    Spring Data JPA为Spring应用程序提供了数据访问层的实现.这是一个非常方便的组件,因为它不会重新发明每个新应用程序的数据访问方式,因此您可以花更多时间来实现业务逻辑.使用Spring ...

  10. spring源码分析---IOC(1)

    我们都知道spring有2个最重要的概念,IOC(控制反转)和AOP(依赖注入).今天我就分享一下spring源码的IOC. IOC的定义:直观的来说,就是由spring来负责控制对象的生命周期和对象 ...