flask框架自帶的代理對象有四個,分別是request,session,g和current_app,各自的含義咱們在前面已經詳細分析過。使用代理而不是顯式的對象的主要目的在於這四個對象使用太過頻繁,貫穿整個請求週期,顯式傳遞很容易形成循環導入的問題,須要一個第三方的對象來進行解耦。python
代理模式是程序設計的一種結構模式,其目的是使調用者和執行者之間不發生直接的關係,而是使用一個代理人,這樣調用者和執行者就進行了解耦,能夠避免許多的問題。flask
代理模式使用的場景:session
爲真實目標類建立一個對象的代價是昂貴的,而建立代理類很簡單;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就是flask框架的werkzeug工具實現的一個代理對象,它接收一個可調用的無參數函數做爲參數,內部實現了object對象全部的魔法方法的重寫,理論上能夠代理任何的對象,無論這個對象的結構是怎麼樣的。this
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(Boss) def get_boss(Obj=None): return Obj.real_obj proxy_boss = LocalProxy(partial(get_boss, other))
get_boss這種形式是動態代理,也就是說在進程運行中因爲OtherObj的real_obj屬性可能發生變化,proxy_boss代理的對象可能發生改變。代理