LocalStack源码
class LocalStack(object):
def __init__(self):
self._local = Local()
def __release_local__(self):
self._local.__release_local__()
def _get__ident_func__(self):
return self._local.__ident_func__
def _set__ident_func__(self, value):
object.__setattr__(self._local, "__ident_func__", value)
__ident_func__ = property(_get__ident_func__, _set__ident_func__)
del _get__ident_func__, _set__ident_func__
def __call__(self):
def _lookup():
rv = self.top
if rv is None:
raise RuntimeError("object unbound")
return rv
return LocalProxy(_lookup)
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 None
虽然Local是通过key-value管理对象,但是LocalStack引入了类型为list的stack,这样看起来像stack。
"""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
另外__call__
的实现,使得每次调用拿的都是最新push的对象。
def __call__(self):
def _lookup():
rv = self.top
if rv is None:
raise RuntimeError("object unbound")
return rv
return LocalProxy(_lookup)
使用LocalStack
from werkzeug.local import LocalStack
class Request(object):
def __init__(self):
self.url = 'baidu.com'
class User(object):
def __init__(self):
self.owner = 'www'
request = Request()
user = User()
ls = LocalStack()
ls.push(request)
r = ls()
print(r)
ls.push(user)
# 特别注意的是这里是User对象,调用__call__
r = ls()
print(r)
输出结果:
<main.Request object at 0x7f1566d42e10>
<main.User object at 0x7f1566d42da0>
拿到了Request和User对象实例。
网友评论