python3-开发进阶Flask的基础(3)
程序员文章站
2022-10-04 22:05:41
上篇我们大概简单描述了一下上下文管理,这篇来具体来说说, 一、前奏 1、一个新名词:偏函数 (可以帮你自动传参数) 2、super和执行类的区别? 3、面向对象中特殊方法 setattr/getattr注意事项: 四、栈 基于列表实现的一个栈: 5、Local类 这个是我们自己写的,我们再去看看fl ......
上篇我们大概简单描述了一下上下文管理,这篇来具体来说说,
- 上下管理的request
- 上下管理的session
- 第三方组件:flask-session
- pymysql操作数据库 数据库连接池
一、前奏
1、一个新名词:偏函数 (可以帮你自动传参数)
import functools #装饰器用过的模块 def index(a,b): return a+b new_fun=functools.partial(index,666) #666当作第一个参数 #原来的调用 # ret=index(1,2) # # print(ret) ret=new_fun(1) #偏函数,帮助开发者自动传递参数 print(ret)
2、super和执行类的区别?
class base(object): def func(self): print('base.func') class foo(base): def func(self): #方式一:根据mro的顺序执行方法 # super().func() #方式二:主动执行base类的方法 # base.func(self) print('foo.func') obj=foo() obj.func() print(obj.__mro__)
3、面向对象中特殊方法 setattr/getattr注意事项:
class foo(object): def __init__(self): #self.duoduo={} 直接定于会发现调用__setattr__方法时,还没有生成会报错 object.__setattr__(self,'duoduo',{}) def __setattr__(self, key, value): print(key,value,self.duoduo) obj=foo() print(obj.duoduo)
四、栈
基于列表实现的一个栈:
class stack(object): def __init__(self): self.data=[] def push(self,val): self.data.append(val) def pop(self): return self.data.pop() _stack=stack() _stack.push('大娃') _stack.push('二娃') print(_stack.pop()) print(_stack.pop())
5、local类
try: from greenlet import getcurrent as get_ident #获取协程的唯一标记 except: from threading import get_ident #获取线程的唯一标记 class local(object): def __init__(self): object.__setattr__(self,'storage',{}) def __setattr__(self, key, value): ident=get_ident() if ident not in self.storage: self.storage[ident]={key,value} else: self.storage[ident][key]=value def __getattr__(self, item): ident=get_ident() if ident in self.storage: return self.storage[ident].get(item)
这个是我们自己写的,我们再去看看flask中的local类
from flask import globals #点globals _request_ctx_stack = localstack() #点localstack() self._local = local() #点local
先看看上面导入的模块:一样的,优先协程,然后线程
__slots__,只能访问什么属性的范围
6、全局变量只有在初次加载时执行
二、上下文管理 request
1、wsgi 初步处理请求
2 、 __call__方法 执行wsgi_app
3、ctx=requestcontextsession,request) 再执行 ctx.push()
4、localstack对象 把ctx对象添加到local中
5、local 存数据的时__storage__={'唯一标识':{stack:[ctx,]}}
6、视图函数
上下文管理:session
就一个流程,别的基本上一样,
最后通过localstack获取ctx中的session,给session赋值(从cookie中读取数据)
三、flask-session
先下载第三方的库
pip3 install flask-session
用法:
import redis from flask import flask from flask.sessions import securecookiesessioninterface from flask_session import session duo=flask(__name__) #duo.session_interface=securecookiesessioninterface() #duo.session_interface=redissessioninterface() duo.config['session_type']='redis' duo.config['session_type']=redis.redis(host='11.1.11.1',port=6379,password='123456') session(duo)
我们来看看session里面是什么:
app.session_interface赋值,再来看看sef._get_interface(app)
这下我们来说说他的原理:
最开始请求进来的时候,这时是根本没有sesiion,找到他的session,执行open_session
执行完open_session,就要保存在浏览器上执行save_session
保存好后,下次再来访问:
总结:
- session 数据保存到redis session:随机字符串(每个线程或协程都不一样)
- 随机字符串返回给用户
查看源码
from flask_session import redissessioninterface
四、数据库连接池
pip3 install dbutils
创建一批连接到连接池,供所有线程共享使用。
import time import pymysql import threading from dbutils.pooleddb import pooleddb, shareddbconnection pool = pooleddb( creator=pymysql, # 使用链接数据库的模块 maxconnections=6, # 连接池允许的最大连接数,0和none表示不限制连接数 mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建 maxcached=5, # 链接池中最多闲置的链接,0和none不限制 maxshared=3, # 链接池中最多共享的链接数量,0和none表示全部共享。
ps: 无用,因为pymysql和mysqldb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,
所以永远是所有链接都共享。 blocking=true, # 连接池中如果没有可用连接后,是否阻塞等待。true,等待;false,不等待然后报错 maxusage=none, # 一个链接最多被重复使用的次数,none表示无限制 setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."] ping=0, # ping mysql服务端,检查是否服务可用。
# 如:0 = none = never, 1 = default = whenever it is requested,
2 = when a cursor is created, 4 = when a query is executed, 7 = always host='127.0.0.1', port=3306, user='root', password='123', database='db', charset='utf8' ) def func(): # 检测当前正在运行连接数的是否小于最大链接数,如果不小于则:等待或报raise toomanyconnections异常 # 否则 # 则优先去初始化时创建的链接中获取链接 steadydbconnection。 # 然后将steadydbconnection对象封装到pooleddedicateddbconnection中并返回。 # 如果最开始创建的链接没有链接,则去创建一个steadydbconnection对象,再封装到pooleddedicateddbconnection中并返回。 # 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。 conn = pool.connection() cursor = conn.cursor(pymysql.cursors.dictcursor) #pymsql cursor.execute('select * from tb1') result = cursor.fetchall() conn.close() func()
注意:
使用数据库要用连接池
封装sqlhelper
上一篇: python随笔--根据号码查询归属地
推荐阅读
-
python3-开发面试题(python)6.24基础篇(3)
-
python3-开发进阶Flask的基础(3)
-
python3-开发进阶Django-debug-toolbar的配置和Django logging的配置
-
python3全栈开发-补充UDP的套接字、操作系统、并发的理论基础
-
python3开发进阶-Django视图(View)的常见用法
-
python3-开发进阶Flask的基础(5)
-
《BREW进阶与精通——3G移动增值业务的运营、定制与开发》连载之8---Symbian,Windows Mobile,Palm,Linux,J2ME
-
python3-开发面试题(python)6.22基础篇(1)
-
python3-开发进阶Flask的基础(2)
-
python3开发进阶-Django框架学习前的小项目(一个简单的学员管理系统)