python cookbook第三版学习笔记十七:委托属性
我们想在访问实例的属性时能够将其委托到一个内部持有的对象上,这经常用到代理机制上
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第三版学习笔记十七:委托属性的更多相关文章
- python cookbook第三版学习笔记十:类和对象(一)
类和对象: 我们经常会对打印一个对象来得到对象的某些信息. class pair: def __init__(self,x,y): self.x=x self. ...
- python cookbook第三版学习笔记六:迭代器与生成器
假如我们有一个列表 items=[1,2,3].我们要遍历这个列表我们会用下面的方式 For i in items: Print i 首先介绍几个概念:容器,可迭代对象,迭代器 容器是一种存储数据 ...
- python cookbook第三版学习笔记 一
数据结构 假设有M个元素的列表,需要从中分解出N个对象,N<M,这会导致分解的值过多的异常.如下: record=['zhf','zhf@163.com','775-555-1212','847 ...
- python cookbook第三版学习笔记十三:类和对象(三)描述器
__get__以及__set__:假设T是一个类,t是他的实例,d是它的一个描述器属性.读取属性的时候T.d返回的是d.__get__(None,T),t.d返回的是d.__get__(t,T).说法 ...
- python cookbook第三版学习笔记二十:可自定义属性的装饰器
在开始本节之前,首先介绍下偏函数partial.首先借助help来看下partial的定义 首先来说下第一行解释的意思: partial 一共有三个部分: (1)第一部分也就是第一个参数,是一个函数, ...
- python cookbook第三版学习笔记十六:抽象基类
假设一个工程中有多个类,每个类都通过__init__来初始化参数.但是可能有很多高度重复且样式相同的__init__.为了减少代码.我们可以将初始化数据结构的步骤归纳到一个单独的__init__函数中 ...
- python cookbook第三版学习笔记十五:property和描述
8.5 私有属性: 在python中,如果想将私有数据封装到类的实例上,有两种方法:1 单下划线.2 双下划线 1 单下划线一般认为是内部实现,但是如果想从外部访问的话也是可以的 2 双下划线是则无法 ...
- 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 ...
- python cookbook第三版学习笔记十三:类和对象(四)描述器
__get__以及__set__:假设T是一个类,t是他的实例,d是它的一个描述器属性.读取属性的时候T.d返回的是d.__get__(None,T),t.d返回的是d.__get__(t,T).说法 ...
随机推荐
- [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 ...
- iOS开发:Framework的创建
转载自:http://jonzzs.cn/2017/06/01/iOS%20开发笔记/[iOS%20开发]将自己的框架打包成%20Framework%20的方法/ 环境:Xcode 8 创建 Fram ...
- Recycling Settings for an Application Pool <recycling>
Overview The <recycling> element contains configuration settings that control the conditions t ...
- jQuery异步框架探究2:jQuery.Deferred方法
(本文针对jQuery1.6.1版本号)关于Deferred函数的描写叙述中有一个词是fledged,意为"羽翼丰满的",说明jQuery.Deferred函数应用应该更成熟. 这 ...
- 网站拓扑图(来自qq)
- xcode几个常用的快捷键
command + ctrl + e 修改变量的名称:选中某个变量,按下该快捷键,可以批量修改对应的变量名称 command + shift + j 定位到文档导航界面,然后通过上下方向键,可以快 ...
- CSS 温故而知新 断句失败
设置了一定的宽度和高度.但无论是下面哪句都无效. word-break: break-word; word-wrap: break-word; 原因竟然是因为 /* white-space: nowr ...
- leetCode(37):Implement Queue using Stacks
Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of ...
- nginx的proxy_pass到$host的问题
今天在配置一个location的时候,希望使用一个变量如$host来指示nginx代理: location /test/ { proxy_pass http://$host; } 如你想不到,这个配置 ...
- Apache中KeepAlive 配置
引子 先来分析一个Yslow 测试的一个页面的前端性能. 这里所有的请求是指http请求,对于一个请求各个阶段的划分,阻挡->域名解析->建立连接->发送请求->等待响应-&g ...