- Werkzeug的Local系列(3) - 模仿Werkzeug
- Werkzeug的Local系列(1) - 属性__setatt
- Werkzeug的Local系列(6) -LocalProxy源
- Werkzeug的Local系列(5) -LocalStack源
- Werkzeug的Local系列(4) -Local源码与使用
- Werkzeug(Flask)之Local、LocalStack
- Flask怎样获得访客的user agent
- flask/odoo/werkzeug的url mapping
- Flask的ThreadLocal和LocalProxy
- Werkzeug的Local系列(2) - 属性的代理访问
模仿Werkzeug的Local和LocalProxy
根据之前的需求,尝试编写代码:
class Request(object):
def __init__(self):
self.url = 'baidu.com'
class User(object):
def __init__(self):
self.owner = 'www'
class Local:
def __init__(self):
self._objs = {}
self._objs['request'] = Request()
self._objs['user'] = User()
def __getattr__(self, name):
print('Local.__getattr__')
return self._objs[name]
def __call__(self, name):
return LocalProxy(self, name)
class LocalProxy(object):
def __init__(self, local, name):
self._local = local
self._name = name
def _get_current_obj(self):
print('_get_current_obj')
return getattr(self._local, self._name)
def __getattr__(self, name):
print('SpamProxy.__getattr__')
return getattr(self._get_current_obj(), name)
def __setattr__(self, name ,value):
if name.startswith('_'):
super().__setattr__(name, value)
else:
setattr(self._obj, name, value)
def __delattr__(self, name):
print('SpamProxy.__delattr__')
if name.startswith('_'):
super().__delattr__(name)
else:
print('SpamProxy', name)
delattr(self._obj, name)
l = Local()
request = l('request')
print(request)
print(request.url)
user = l('user')
print(user.owner)
输出结果:
<main.LocalProxy object at 0x7f74e1b0d2b0>
SpamProxy.getattr
_get_current_obj
Local.getattr
baidu.com
SpamProxy.getattr
_get_current_obj
Local.getattr
www
2 结论
通过该实例,我们实现了:
- Local管理Request和User对象
- LocalProxy实现代理访问Local管理的多个对象
当然Werkzeug的Local实现比示例复杂:
- Local的_objs增加线程(协程)维度
- Request和User等管理的对象是动态添加,示例中是固定的
后面的文章将接讲解Werkzeug的Local、LocalProxy、LocalManager和LocalProxy。
网友评论