python委托模式详细解释

收集了网上的三个例子,然后做了些注释:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


class Wrapper:
    def __init__(self, obj):
        self.wrapper = obj
        print self.wrapper
        print type(self.wrapper)
        print"-"*100

    def __getattr__(self, item):
        print("trace:", item)
        return getattr(self.wrapper, item)


if __name__ == '__main__':
    x = Wrapper([1, 2, 3, 4])
    x.append(35)
    x.remove(2)
    print(x.wrapper)  # [1,3,4,35]

  1. __init__(self,obj)方法中传入一个被委托对象。
  2. 通过重写__getattr__(self,item)方法,拦截外部对象的属性调用
  3. __getattr__(self,item)中,将拦截到的属性,让被委托对象去使用。

    python 中的属性概念,和Java中的属性概念是不同的。Java中的属性,就是指类中定义的成员变量,绝对不包含方法。而在python中,任何能以obj.xx形式调用的东西,全部可以称为属性。无论是方法,还是变量,还是对象。

所以上述代码中调用x.append(N),实际上是让x的属性wrapper去调用append(N)方法。

上面传入的参数是[1,2,3,4],是一个list类型的对象,该对象自然可以调用append remove这些方法。

这个转载自:

http://blog.csdn.net/DucklikeJAVA/article/details/73729212

---------------------------------------------------------------------------------------------------------------

#-*- encoding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
class A:
    def f_one(self, x):
        print"here is f_one"
        print"x=",x
        print"-"*100

    def f_two(self):
        print"here is f_two"
        print"-"*100

class B(A):
    def __init__(self):
        self._a = A()#也就是说在类B中有个成员变量例化了类A,_a是A的对象,不要太在意_a这个奇怪的名字
    
    def f_one(self, x):
        return self._a.f_one(x)

    def f_two(self):
        return self._a.f_two()

    def f_three(self):
        print"Here is B(A)"
if __name__ == '__main__':
    b_test=B()
    x=6
    b_test.f_one(x)
    b_test.f_two()
    
 

这就是一个最简单的委托,将A的实例在B类中生成,并且转化为B的一个私有属性,当我们需要访问A的属性的时候,加入我们只暴露B出来,这时候就只能通过B类来访问A类,这就达到了委托的效果。

上面的这种方法使用情景为:有几个方法需要委托,当我们需要大量委托的时候这显然不是一个好办法,这时候还有另一个更巧妙的方法:getattr()方法,下面请看代码:

#-*- encoding:utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
class A:
    def f_one(self, x):
        print"here is f_one"
        print"x=",x
        print"-"*100

    def f_two(self):
        print"here is f_two"
        print"-"*100

class B(A):
    def __init__(self):
        self._a = A()

    def f_three(self):
        pass

    def __getattr__(self, name):#相当于重写了__getattr__,利用__getattr_来实现委托的效果(其实委托就是甩锅的意思啦,B搞不定,甩锅给A)
        return getattr(self._a, name)
if __name__ == '__main__':
    b_test=B()
    x=6
    b_test.f_one(x)
    b_test.f_two()


这里要注意一下这个新的方法,这个方法的作用是用来查找所有的属性,放在这里时,如果代码中尝试访问这个类中不存在的属性时,会去调用实例_a中的属性,这样就可以实现大量的代理。



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值