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).说法 ...
随机推荐
- azkaban2.5 具体配置以及使用方式
azkaban支持shell.java.mapreduce以及hive的工作流调度,在对这些不同类型任务调度之前须要配置所相应的插件:azkaban总体分为两部分azkaban executor se ...
- hdu 5284 wyh2000 and a string problem(没有算法,仅仅考思维,字符数组得开20万,不然太小了)
代码: #include<cstdio> #include<cstring> using namespace std; char s[200000]; int main() { ...
- 完美拖拽 &&仿腾讯微博效果&& 自定义多级右键菜单
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 在windows上一键编译各种版本的protobuf(2017-12-05修改)
所需工具 : cmake for windows 和 git for windows 原理:protobuf 是google的一个开源项目,其源代码在github上可以下载到,并且源码都采用cm ...
- nginx 做前端代理时proxy参数配置
1.后台可登录: proxy_connect_timeout 300s; proxy_send_timeout ; proxy_read_timeout ; proxy_buffer_size 256 ...
- javascript 在js文件中获取路径
如果在*.js文件中获取当自己当前的路径是很重要的. 举个例子,如果一个css文件中引用图片,如background-img: url('./Images/bg.png').那么图片的路径,是相对于c ...
- Windows安装Redis的php扩展
Redis是一种常用的非关系型数据库,主要用作数据缓存,数据保存形式为key-value,键值相互映射.它的数据存储跟MySQL不同,它数据存储在内存之中,所以数据读取相对而言很快,用来做高并发非常不 ...
- Laravel5.4使用Memcached缓存
修改默认的缓存驱动 Laravel默认的缓存驱动是file,想要切换为Memcached需要修改.env文件.把CACHE_DRIVER=file改为CACHE_DRIVER=memcached,改好 ...
- Apache安全和强化的十三个技巧
Apache是一个很受欢迎的web服务器软件,其安全性对于网站的安全运营可谓生死攸关.下面介绍一些可帮助管理员在Linux上配置Apache确保其安全的方法和技巧. 本文假设你知道这些基本知识: 文档 ...
- member access within misaligned address 0x000000000031 for type 'struct ListNode', which requires 8 byte alignment
在做LeetCode的two sum题目的时候,提交代码遇到了如题的runtime error,后来在一篇博客上看到了解决方法. 现有如下结构体: struct ListNode { int val; ...