我们想在访问实例的属性时能够将其委托到一个内部持有的对象上,这经常用到代理机制上

class A:
    def spam(self,x):
        print("class_A:"+str(x))
    def foo(self):
        pass

class B:
    def __init__(self):
        self._a=A()
    def bar(self):
        pass
    def __getattr__(self, item):
        return getattr(self._a,item)

b=B()

b.bar()

b.spam(42)

运行结果:

class_A:42

在这里,当调用b.spam的时候,由于查找不到这个属性,因此调用__getattr__来查找所有的属性。在上面的代码中,在访问B中未定义的方法时就把这个操作委托给A。

对这种方法进行扩展一下,我们可以实现带有状态的对象或状态机。代码如下:

class connection():

def __init__(self):

self.new_state(ClosedConnection)

def new_state(self,newstate):

self.__class__=newstate

def read(self):

raise NotImplementedError()

def write(self):

raise NotImplementedError()

def open(self):

raise NotImplementedError

def close(self):

raise NotImplementedError

class ClosedConnection(connection):

def read(self):

raise RuntimeError('not open')

def write(self,data):

raise RuntimeError('not open')

def open(self):

self.new_state(OpenConnection)

def close(self):

raise RuntimeError('Already closed')

class OpenConnection(connection):

def read(self):

print('reading')

def write(self,data):

print('writing')

def open(self):

raise RuntimeError('Already open')

def close(self):

self.new_state(ClosedConnection)

c=connection()

print(c)

c.read()

执行结果如下,初始状态为ClosedConnection, 调用read的时候提示not open

<__main__.ClosedConnection object at
0x00000250CD984DD8>

Traceback (most recent call last):

File "D:/py_prj/test2/cookbook.py", line 152, in
<module>

c.read()

File "D:/py_prj/test2/cookbook.py", line 130, in read

raise RuntimeError('not open')

RuntimeError: not open

c=connection()

print(c)

c.open()

print(c)

c.read()

c.write('abc')

c.close()

print(c)

调用c.open后状态转移到OpenConnection。此时调用read和write方法则可以正常调用。调用close方法后状态转移到ClosedConnection

<__main__.ClosedConnection object at
0x000001C495E94DA0>

<__main__.OpenConnection object at
0x000001C495E94DA0>

reading

writing

<__main__.ClosedConnection object at
0x000001C495E94DA0>

通过这种方法减少了在代码分支中大量使用ifelse的调用。

python cookbook第三版学习笔记十七:委托属性的更多相关文章

  1. python cookbook第三版学习笔记十:类和对象(一)

    类和对象: 我们经常会对打印一个对象来得到对象的某些信息. class pair:     def __init__(self,x,y):         self.x=x         self. ...

  2. python cookbook第三版学习笔记六:迭代器与生成器

    假如我们有一个列表 items=[1,2,3].我们要遍历这个列表我们会用下面的方式 For i in items:   Print i 首先介绍几个概念:容器,可迭代对象,迭代器 容器是一种存储数据 ...

  3. python cookbook第三版学习笔记 一

    数据结构 假设有M个元素的列表,需要从中分解出N个对象,N<M,这会导致分解的值过多的异常.如下: record=['zhf','zhf@163.com','775-555-1212','847 ...

  4. python cookbook第三版学习笔记十三:类和对象(三)描述器

    __get__以及__set__:假设T是一个类,t是他的实例,d是它的一个描述器属性.读取属性的时候T.d返回的是d.__get__(None,T),t.d返回的是d.__get__(t,T).说法 ...

  5. python cookbook第三版学习笔记二十:可自定义属性的装饰器

    在开始本节之前,首先介绍下偏函数partial.首先借助help来看下partial的定义 首先来说下第一行解释的意思: partial 一共有三个部分: (1)第一部分也就是第一个参数,是一个函数, ...

  6. python cookbook第三版学习笔记十六:抽象基类

    假设一个工程中有多个类,每个类都通过__init__来初始化参数.但是可能有很多高度重复且样式相同的__init__.为了减少代码.我们可以将初始化数据结构的步骤归纳到一个单独的__init__函数中 ...

  7. python cookbook第三版学习笔记十五:property和描述

    8.5 私有属性: 在python中,如果想将私有数据封装到类的实例上,有两种方法:1 单下划线.2 双下划线 1 单下划线一般认为是内部实现,但是如果想从外部访问的话也是可以的 2 双下划线是则无法 ...

  8. python cookbook第三版学习笔记七:python解析csv,json,xml文件

    CSV文件读取: Csv文件格式如下:分别有2行三列. 访问代码如下: f=open(r'E:\py_prj\test.csv','rb') f_csv=csv.reader(f) for f in ...

  9. python cookbook第三版学习笔记十三:类和对象(四)描述器

    __get__以及__set__:假设T是一个类,t是他的实例,d是它的一个描述器属性.读取属性的时候T.d返回的是d.__get__(None,T),t.d返回的是d.__get__(t,T).说法 ...

随机推荐

  1. springboot @Configuration

    有了@Configuration,原来的springBean的配置文件可以去掉了, 原来在application.xml中配置的bean可以配置在@Configuration注解的来类中,使用@Bea ...

  2. 【Excle数据透视表】如何得到数据透视表中某个汇总行的明细数据

    例如: 现在想得到"北京 汇总"的明细数据,该怎么处理呢? 步骤 右键数据透视表任意单元格→数据透视表选项→启用显示明细数据→确定→单击"北京 汇总"行最后一个 ...

  3. BigDecimal舍入模式使用及建议

    1. 八种舍入模式 此节内容参考于 https://my.oschina.net/sunchp/blog/670909. JDK1.5发布的枚举 RoundingMode 对 BigDecimal 的 ...

  4. mongoDB 高级查询语法

    http://www.cnblogs.com/ITAres/articles/2084794.html本文参考自官方的手册:http://www.mongodb.org/display/DOCS/Ad ...

  5. wps如何设置文字环绕图片

    wps在编辑一些文字的时候,经常会插入一些图片,但是插入图片后,文字和图片就被分离开来,整体显得没有那么美观整洁,这个时候就用到了软件的文字环绕功能,那么具体如何设置呢,接下来看教程. 首先打开wps ...

  6. PJSIP dialog inv销毁

    PJSIP的Diaglog(类型为pjsip_dialog) 可以被外部调用,同时PJSIP有自己的机制销毁用户创建的 Dialog,如PJSIP内部销毁了某个Diaglog,用户在不知情的情况下继续 ...

  7. Android下的Handler

    coder是没必要重复造轮子的,写博客亦如此.因为工作忙,学的东西比较多,没法自己来写博客.自己想了个思路就是,把别人的技术精华拿过来,从简到难,慢慢学习.最后提炼,得到自己想学的东西即可,等有时间了 ...

  8. ubuntu16.04上安装深度学习基本框架caffe2 pytorch tensorflow opencv

    anaconda3.5.2.0----python3.6: conda  install   tensorflow-gpu  -y --prefix  /media/wkr/diskHgst/ubun ...

  9. [转]Ubuntu Server命令行更换软件源

    sucd /etc/aptwget http://mirrors.163.com/.help/sources.list.lucidmv sources.list sources.list.backup ...

  10. EXTjs+SpringMVC+Mybatis实现照片的上传,下载,查看关键技术整理

    第一个问题:如何通过Extjs4实现照片上传的布局展示以及本地照片选择后的在一个区域内进行图片预览 实现照片上传的布局展示: items : [ { xtype : 'box', itemId : ' ...