1.当我们代理的理解
代码语言:javascript复制from werkzeug.local import LocalStack, LocalProxy
l_stack = LocalStack()
l_stack.push({
'name': 'wang'})
l_stack.push({
'name': 'wei'})
def get_name():
return l_stack.pop()
# 不用代理
name = get_name()
print(f"name is {name['name']}")
print(f"name is {name['name']}")
# 结果
# wang
# wang
l_stack = LocalStack()
l_stack.push({
'name': 'wang'})
l_stack.push({
'name': 'wei'})
# 代理操作get_name
name2 = LocalProxy(get_name)
print(f"{name2['name']}") # 每次使用name2获取属性,相当于调用一次get_name方法
print(f"{name2['name']}")
# 结果
# wang
# wei
2.flask
框架正是使用了这个代理的特点,可以在全局中获得当前的上下文,比如current_app
,request
,session
和g
# context locals
_request_ctx_stack = LocalStack()
current_app = LocalProxy(lambda: _request_ctx_stack.top.app)
request = LocalProxy(lambda: _request_ctx_stack.top.request)
session = LocalProxy(lambda: _request_ctx_stack.top.session)
g = LocalProxy(lambda: _request_ctx_stack.top.g)
每次我们使用current_app
时,都会从_request_ctx_stack.top.app
的栈顶重新获取,如果不用代理
current_app = _request_ctx_stack.top.app
这样在调用current_app
时则只会获得一次,而且以后都不会再改变
3.代理是如何实现的:
代码语言:javascript复制class LocalProxy(object):
# ... 省略部分代码
__getitem__ = lambda x, i: x._get_current_object()[i] # x是代理对象本身(上例中name2),i是要查询的属性
# 结合 __init__与 _get_current_object()方法来看。
class LocalProxy(object):
__slots__ = ("__local", "__dict__", "__name__", "__wrapped__")
def __init__(self, local, name=None):
object.__setattr__(self, "_LocalProxy__local", local)
object.__setattr__(self, "__name__", name)
if callable(local) and not hasattr(local, "__release_local__"):
object.__setattr__(self, "__wrapped__", local)
def _get_current_object(self):
if not hasattr(self.__local, "__release_local__"):
return self.__local()
try:
return getattr(self.__local, self.__name__)
except AttributeError:
raise RuntimeError("no object bound to %s" % self.__name__)
参考: https://zhuanlan.zhihu.com/p/103376446 https://www.cnblogs.com/daofaziran/p/10826357.html https://www.cnblogs.com/flowell/p/local_local_proxy_local_stack.html https://blog.csdn.net/weixin_38091140/article/details/93592079 https://segmentfault.com/a/1190000007663087 https://blog.tonyseek.com/post/the-context-mechanism-of-flask/ https://cizixs.com/2017/01/13/flask-insight-context/ https://werkzeug.palletsprojects.com/en/1.0.x/ https://www.cnblogs.com/caoxing2017/p/8282530.html https://www.toptal.com/python/pythons-wsgi-server-application-interface https://www.jianshu.com/p/995bd7ae463a
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/185230.html原文链接:https://javaforall.cn