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

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. Angular 学习笔记——ng-animate

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  2. Solidworks 好的测试题模拟题

    题目:按照下图构建草图,注意设置必要的几何约束. 问题:   1.参照下图所示参数时请问其中绿色区域的面积为多少平方毫米?     题目:参照下图绘制草图轮廓,注意图中各线条之间均为相切过渡. 问题: ...

  3. iOS block用作属性封装代码

    @property (copy, nonatomic) void (^actionBlock)(); @property (copy, nonatomic) void (^actionWithPapa ...

  4. liunx下安装第三方Python(PIP安装)

    wget https://pypi.python.org/packages/source/p/pip/pip-6.0.8.tar.gz $ tar zvxf pip-6.0.8.tar.gz $ cd ...

  5. object-c 框架之经常使用结构体

    Foundation 框架定义经常使用结构体.结构体採用object-c 定义:经常使用NSSRange,NSPoint.NSSize,NSRect等 一.NSRange 创建范围结构体. 方法:NS ...

  6. react-native 封装 VedioPlayer 组件

    1.封装组件 src/components/VideoPlayer/index.js /** * 视频播放器 组件(VideoPlayer) */ import React, {Component} ...

  7. react-navigation + react-native-vector-icons

    1.安装 yarn add react-navigation react-native-vector-icons 2.创建 root.js import React, {Component} from ...

  8. 让UITableView进入编辑模式

    1.UITableView对象有一个editing属性,设为YES时,该对象会进入编辑模式(editing mode).表格视图进入编辑模式后,用户可以管理表格中得行,如改变行的排列顺序.增加行或删除 ...

  9. BFS和DFS的java实现

    <pre name="code" class="java"> import java.util.HashMap; import java.util. ...

  10. Python基础之函数与装饰器

    阅读目录 一.为什么要使用函数 二.函数的定义与调用 三.函数返回值 四.函数的参数 五.本章小结 六.装饰器 一.函数流程图: 函数名的命名规则: 1.函数名必须由字母下划线数字组成,不能是关键字和 ...