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

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. [PWA] Disable Text Selection and Touch Callouts in a PWA on iOS

    Because an installed PWA is really just a web app running in a browser, there are some browser behav ...

  2. iOS开发:Framework的创建

    转载自:http://jonzzs.cn/2017/06/01/iOS%20开发笔记/[iOS%20开发]将自己的框架打包成%20Framework%20的方法/ 环境:Xcode 8 创建 Fram ...

  3. Recycling Settings for an Application Pool <recycling>

    Overview The <recycling> element contains configuration settings that control the conditions t ...

  4. jQuery异步框架探究2:jQuery.Deferred方法

    (本文针对jQuery1.6.1版本号)关于Deferred函数的描写叙述中有一个词是fledged,意为"羽翼丰满的",说明jQuery.Deferred函数应用应该更成熟. 这 ...

  5. 网站拓扑图(来自qq)

  6. xcode几个常用的快捷键

    command + ctrl + e   修改变量的名称:选中某个变量,按下该快捷键,可以批量修改对应的变量名称 command + shift + j 定位到文档导航界面,然后通过上下方向键,可以快 ...

  7. CSS 温故而知新 断句失败

    设置了一定的宽度和高度.但无论是下面哪句都无效. word-break: break-word; word-wrap: break-word; 原因竟然是因为 /* white-space: nowr ...

  8. leetCode(37):Implement Queue using Stacks

    Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of ...

  9. nginx的proxy_pass到$host的问题

    今天在配置一个location的时候,希望使用一个变量如$host来指示nginx代理: location /test/ { proxy_pass http://$host; } 如你想不到,这个配置 ...

  10. Apache中KeepAlive 配置

    引子 先来分析一个Yslow 测试的一个页面的前端性能. 这里所有的请求是指http请求,对于一个请求各个阶段的划分,阻挡->域名解析->建立连接->发送请求->等待响应-&g ...