flask基礎之LocalProxy代理對象(八)
阿新 • • 發佈:2018-12-07
t對象 try 周期 所有 == 內部實現 前言 python 調用
前言
flask框架自帶的代理對象有四個,分別是request,session,g和current_app,各自的含義我們在前面已經詳細分析過。使用代理而不是顯式的對象的主要目的在於這四個對象使用太過頻繁,貫穿整個請求周期,顯式傳遞很容易造成循環導入的問題,需要一個第三方的對象來進行解耦。
代理模式簡介
代理模式是程序設計的一種結構模式,其目的是使調用者和執行者之間不發生直接的關系,而是使用一個代理人,這樣調用者和執行者就進行了解耦,可以避免許多的問題。
代理模式使用的場景:
為真實目標類創建一個對象的代價是昂貴的,而創建代理類很簡單;
對象必須防止被用戶直接使用。
當實際請求的時候,為真實目標類創建一個對象會有延遲。
class Boss(object): def task1(self): print(‘this is task1‘) def task2(self): print(‘this is task2‘) class Proxy(object): def __init__(self, obj): self.proxy = obj def task1(self): self.proxy.task1() def task2(self): self.proxy.task2() proxy_boss = Proxy(Boss()) class Client(object): def do_something(self): proxy_boss.task1() if __name__ == ‘__main__‘: c = Client() c.do_something()
上述的Boss實例不需要顯式傳遞,受到了保護;Proxy對象相當於一個接口的作用。
LocalProxy代理對象
LocalProxy就是flask框架的werkzeug工具實現的一個代理對象,它接收一個可調用的無參數函數作為參數,內部實現了object對象所有的魔法方法的重寫,理論上可以代理任何的對象,不管這個對象的結構是怎麽樣的。
class LocalProxy(object): def __init__(self, local, name=None): object.__setattr__(self, ‘_LocalProxy__local‘, local) object.__setattr__(self, ‘__name__‘, name) def _get_current_object(self): if not hasattr(self.__local, ‘__release_local__‘): return self.__local() # 代理對象local必須是可調用的 try: return getattr(self.__local, self.__name__) except AttributeError: raise RuntimeError(‘no object bound to %s‘ % self.__name__)
如果我們想在項目中的任何地方使用我們自己的全局代理對象,我們可以這樣做:
# myproxy.py
from werkzeug.local import LocalProxy
class Boss(object):
def pop(self):
print(‘Ok‘)
return ‘OK‘
class OtherObj(object):
def __init__(self,Obj):
self.real_obj = Obj()
other = OtherObj()
def get_boss(Obj=None):
return Obj.real_obj
proxy_boss = LocalProxy(partial(get_boss, other))
get_boss這種形式是動態代理,也就是說在進程運行中由於OtherObj的real_obj屬性可能發生變化,proxy_boss代理的對象可能發生改變。
參考
- https://dormousehole.readthedocs.io/en/latest/
flask基礎之LocalProxy代理對象(八)