flask基础之LocalProxy代理对象(八)

前言

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代理对象

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代理的对象可能发生改变。代理

参考

相关文章
相关标签/搜索