flask的request和session设置方式比较新颖,如果没有这种方式,那么就只能通过参数的传递。
flask是如何做的呢?
1. 本地线程,保证即使是多个线程,自己的值也是互相隔离。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#!/usr/bin/env python# -*- coding:utf-8 -*-import threadinglocal_values = threading.local()def func(num): local_values.name = num import time time.sleep(1) print(local_values.name, threading.current_thread().name)for i in range(20): th = threading.Thread(target=func, args=(i,), name='线程%s' % i) th.start() |
2. 上下文原理
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#!/usr/bin/env python# -*- coding:utf-8 -*-from functools import partialfrom flask.globals import LocalStack, LocalProxyls = LocalStack()class RequestContext(object): def __init__(self, environ): self.request = environdef _lookup_req_object(name): top = ls.top if top is None: raise RuntimeError(ls) return getattr(top, name)session = LocalProxy(partial(_lookup_req_object, 'request'))ls.push(RequestContext('c1')) # 当请求进来时,放入print(session) # 视图函数使用print(session) # 视图函数使用ls.pop() # 请求结束popls.push(RequestContext('c2'))print(session)ls.push(RequestContext('c3'))print(session) |
3. Flask内部实现
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
#!/usr/bin/env python# -*- coding:utf-8 -*-from greenlet import getcurrent as get_identdef release_local(local): local.__release_local__()class Local(object): __slots__ = ('__storage__', '__ident_func__') def __init__(self): # self.__storage__ = {} # self.__ident_func__ = get_ident object.__setattr__(self, '__storage__', {}) object.__setattr__(self, '__ident_func__', get_ident) def __release_local__(self): self.__storage__.pop(self.__ident_func__(), None) 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)class LocalStack(object): def __init__(self): self._local = Local() def __release_local__(self): self._local.__release_local__() def push(self, obj): """Pushes a new item to the stack""" rv = getattr(self._local, 'stack', None) if rv is None: self._local.stack = rv = [] rv.append(obj) 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: release_local(self._local) return stack[-1] else: return stack.pop() @property def top(self): """The topmost item on the stack. If the stack is empty, `None` is returned. """ try: return self._local.stack[-1] except (AttributeError, IndexError): return Nonestc = LocalStack()stc.push(123)v = stc.pop()print(v) |
浙公网安备 33010602011771号