Flask之上下文管理和flash_session的使用
上下文管进阶理解
1.偏函数
import functools def index(a1,a2): return a1 + a2 # 原来的调用方式 # ret = index(1,23) # print(ret) # 偏函数,帮助开发者自动传递参数 new_func = functools.partial(index,666) ret = new_func(1) print(ret)
2.执行父类方法
class Base(object): def func(self): print('Base.func') class Foo(Base): def func(self): # 方式一:根据mro的顺序执行方法 # super(Foo,self).func() # 方式二:主动执行Base类的方法 # Base.func(self) print('Foo.func') obj = Foo() obj.func() # print(Foo.__mro__)
3、面向对象的特殊方法
一 class Foo(object): def __init__(self): self.storage = {} # object.__setattr__(self,'storage',{}) def __setattr__(self, key, value): print(key,value) obj = Foo() obj.xx = 123 结果 storage {} xx 123 二 class Foo(object): def __init__(self): self.storage = {} # object.__setattr__(self,'storage',{}) def __setattr__(self, key, value): print(key,value,self.storage) # 打印self.storage会报错,因为实例化对象先执行 #init,init中self.storage会触发seattr方法,seattr中的self.storge没有定义 obj = Foo() obj.xx = 123 三 class Foo(object): def __init__(self): # self.storage = {} object.__setattr__(self,'storage',{}) def __setattr__(self, key, value): print(key,value,self.storage) obj = Foo() obj.xx = 123
4、Flask Local源码
local是用来给每个线程或者协程开辟一个空间
try: from greenlet import getcurrent as get_ident except: from threading import get_ident class Local(object): __slots__ = ('__storage__', '__ident_func__') def __init__(self): # __storage__ = {1231:{'stack':[]}} object.__setattr__(self, '__storage__', {}) object.__setattr__(self, '__ident_func__', get_ident) def __getattr__(self, name): try: return self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name) def __setattr__(self, name, value): ident = self.__ident_func__() storage = self.__storage__ try: storage[ident][name] = value except KeyError: storage[ident] = {name: value} def __delattr__(self, name): try: del self.__storage__[self.__ident_func__()][name] except KeyError: raise AttributeError(name)
5、LocalStack源码
localstack 维护local的列表,维护成一个栈
class LocalStack(object): def __init__(self): self._local = Local() def push(self,value): rv = getattr(self._local, 'stack', None) # self._local.stack =>local.getattr if rv is None: self._local.stack = rv = [] # self._local.stack =>local.setattr rv.append(value) # self._local.stack.append(666) return rv def pop(self): """Removes the topmost item from the stack, will return the old value or `None` if the stack was already empty. """ stack = getattr(self._local, 'stack', None) if stack is None: return None elif len(stack) == 1: return stack[-1] else: return stack.pop() def top(self): try: return self._local.stack[-1] except (AttributeError, IndexError): return None
源码入口
app.__call__ app.wsgi_app
上下文管理request简易流程图
flash_session的使用
flask-session pip3 install flask-session 掌握: - 使用 import redis from flask import Flask,request,session from flask.sessions import SecureCookieSessionInterface from flask_session import Session app = Flask(__name__) # app.session_interface = SecureCookieSessionInterface() # app.session_interface = RedisSessionInterface() app.config['SESSION_TYPE'] = 'redis' app.config['SESSION_REDIS'] = redis.Redis(host='140.143.227.206',port=6379,password='1234') Session(app) @app.route('/login') def login(): session['user'] = 'alex' return 'asdfasfd' @app.route('/home') def index(): print(session.get('user')) return '...' if __name__ == '__main__': app.run() - 原理: - session数据保存到redis session:随机字符串1:q23asifaksdfkajsdfasdf session:随机字符串2:q23asifaksdfkajsdfasdf session:随机字符串3:q23asifaksdfkajsdfasdf session:随机字符串4:q23asifaksdfkajsdfasdf session:随机字符串5:q23asifaksdfkajsdfasdf - 随机字符串返回给用户。 随机字符串 源码: from flask_session import RedisSessionInterface
I can feel you forgetting me。。 有一种默契叫做我不理你,你就不理我