一、session实现原理
二、自定义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):
ident = get_ident()
if ident in self.DIC:
return self.DIC[ident].get(item)
return None
def __setattr__(self, 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.xxxxx = i
time.sleep(2)
print(obj.xxxxx,i)
for i in range(10):
t = threading.Thread(target=task,args=(i,))
t.start()
三、偏函数
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)
四、栈
class Stack(object):
def __init__(self):
self.data = []
def push(self,val):
self.data.append(val)
def pop(self):
return self.data.pop()
def top(self):
return self.data[-1]
_stack = Stack()
_stack.push('佳俊')
_stack.push('咸鱼')
print(_stack.pop())
print(_stack.pop())
五、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)
obj = Local() # 实例化Local对象,在实例化完执行了__init__方法,创建了__storage__={},__ident_func__=get_ident
obj.stack = [] # 执行了__setattr__,创建了{ident:{stack:[]}} 将stack维护成一个栈
obj.stack.append('佳俊') # 执行了__setattr__,创建了{ident:{stack:["佳俊"]}}
obj.stack.append('咸鱼')
print(obj.stack) # 执行了__getattr__方法取出了佳俊
print(obj.stack.pop())
print(obj.stack)
六、LocalStack
import functools
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):
# name=stack
# 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)
"""
__storage__ = {
12312: {stack:[ctx(session/request) ,]}
}
"""
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
class RequestContext(object):
def __init__(self):
self.request = "xx"
self.session = 'oo'
_request_ctx_stack = LocalStack()
_request_ctx_stack.push(RequestContext())
def _lookup_req_object(arg):
ctx = _request_ctx_stack.top()
return getattr(ctx,arg) # ctx.request / ctx.session
request = functools.partial(_lookup_req_object,'request')
session = functools.partial(_lookup_req_object,'session')
print(request())
print(session())
七、slots
class Foo(object):
__slots__ = ('name',) # 只能取name
def __init__(self):
self.name = 'alex'
# self.age = 18
obj = Foo()
print(obj.name)
八、将session存在redis中
import redis
from flask import Flask,request,session
from flask.sessions import SecureCookieSessionInterface
from flask_session import Session
app = Flask(__name__)
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
九、上下文管理图文