# 从LocalProxy(partial(_lookup_req_object, 'request'))看来
# 通过调用self.__local()方法,我们得到了 partial(_lookup_req_object, 'request')()
# 也就是 ``_request_ctx_stack.top.request``
return self.__local()
try:
return getattr(self.__local, self.__name__)
except AttributeError:
raise RuntimeError('no object bound to %s' % self.__name__)
# 接下来就是一大段一段的Python的魔法方法了,Local Proxy重载了(几乎)?所有Python
# 内建魔法方法,让所有的关于他自己的operations都指向到了_get_current_object()
# 所返回的对象,也就是真正的被代理对象。
... ...
__setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v)
__delattr__ = lambda x, n: delattr(x._get_current_object(), n)
__str__ = lambda x: str(x._get_current_object())
__lt__ = lambda x, o: x._get_current_object() < o
__le__ = lambda x, o: x._get_current_object() <= o
__eq__ = lambda x, o: x._get_current_object() == o
__ne__ = lambda x, o: x._get_current_object() != o
__gt__ = lambda x, o: x._get_current_object() > o
__ge__ = lambda x, o: x._get_current_object() >= o
... ...
事情到了这里,我们在文章开头的第二个疑问就能够得到解答了,我们之所以不需要使用get_request() 这样的方法调用来获取当前的request对象,都是LocalProxy的功劳。
LocalProxy作为一个代理,通过自定义魔法方法。代理了我们对于request的所有操作, 使之指向到真正的request对象。
怎么样,现在知道了 request.args 不是它看上去那么简简单单的吧。
现在,让我们来看看第二个问题,在多线程的环境下,request是怎么正常工作的呢? 还是让我们回到globals.py吧:
from functools import partial
from werkzeug.local import LocalStack, LocalProxy
def _lookup_req_object(name):
top = _request_ctx_stack.top
if top is None:
raise RuntimeError('working outside of request context')
return getattr(top, name)
# context locals










