28 - 生成器交互-__slots__-未实现异常
1 生成器交互
生成器提供了一个send方法用于动态的和生成器对象进行交互。怎么理解的呢?看下面的例子:
def generator():
a = 0
while True:
position = yield a # 格式
if position:
a = position
a += 1
g = generator()
print(next(g))
g.send(10)
print(next(g))
print(next(g))
上面的 变量 = yield 返回值,是生成器提供的交互格式,当我们使用生成器对象的send方法时,实参就会被传递给这里的position变量,从而在函数外部来控制函数内部的运行,同时send和next一样可以推动生成器的运行。
import time
import random
class Person:
def __init__(self, name):
self.name = name
def eat(self):
while True:
something = yield
print('{} is eating {}'.format(self.name, something))
daxin = Person('daxin')
g = daxin.eat()
next(g)
count = 0
while True:
time.sleep(random.randrange(3))
g.send('包子-{}'.format(count))
count += 1
这个例子看起来很鸡肋,但是想一下,如果count以上的代码在另一个线程中,是不是就实现了不同线程之间的切换?
2 slots
字典为了提升查询效率,必须用空间换时间。一般来说一个实例,属性多一点,都存储在字典中便于查询,问题不大,但是如果数百万个实例,那么字典占用的空间就很大了,那么是否可以把类的__dict__属性省了?__slots__就是干这个事情的。
class A:
def __init__(self):
self.name = 'daxin'
self.age = 20
self.country = 'China'
self.language = 'Chinese'
... ...
a = A()
实例化对象时,它的属性信息都会存放在实例自己的__dict__字典中去,由于没办法固定实例的属性个数,所以这个字典就会很大。比如__dict__申请了300间客房,而只有4个客人住,并且每个实例都是这样。当使用了__slots__时
class A:
__slots__ = ['name','age']
def __init__(self):
self.name = 'daxin'
self.age = 20
def say(self):
pass
def hello(self):
pass
a = A()
a.name = 'tom'
a.sex = 'Man' # 无法设置,因为__slots__没有允许
print(a.__class__.__dict__) # {'__module__': '__main__', '__slots__': ['name', 'age'], '__init__': <function A.__init__ at 0x0000022422379950>, 'say': <function A.say at 0x00000224223799D8>, 'hello': <function A.hello at 0x0000022422379A60>, 'age': <member 'age' of 'A' objects>, 'name': <member 'name' of 'A' objects>, '__doc__': None}
当类使用了__slots__属性时:
- 实例的属性被__slots__约束,包括在__init__函数中使用self设置的属性。
- 实例的__dict__是在实例化时由__new__方法构建的,当设置了__slots__属性时,__new__方法不会为实例创建__dict__属性字典
- 父类的__slots__对应着子类属性名称(列表或元组)。
- 另外还存在属性名称对应的对象,可以理解为类描述器东西。
- __slots__只约束实例的属性,并不约束实例的方法(实例没有方法,实例是被绑定在类中定义的方法上的)。
- 访问实例属性时,会被映射到对应的类的描述器上(数据描述器),其内部为每个实例构建了专门的对象存储。(具体实现是用偏移地址来记录描述器,通过公式可以直接计算出其在内存中的实际地址,通过直接访问内存获得。)
定义了__slots__时,指定的属性都变为了描述器。
换句话说:__slots__告诉解释器,实例的属性都叫什么,一般来说,既然要节约内存,最好还是使用元组比较好,一旦类提供了__slots__,就阻止实例产生__dict__来保存实例的属性。__slots__不影响子类,不会被继承,但如果父类没有实现__slots__方法,那么子类的就无法生效.
使用建议:为了正确使用__slots__,最好直接继承object。如有需要用到其他父类,则父类和子类都要定义__slots__,还要记得子类的__slots__会覆盖父类的__slots__。除非所有父类的__slots__都为空,否则不要使用多继承。
以上参考自:
https://stackoverflow.com/questions/472000/usage-of-slots
http://code.activestate.com/recipes/532903-how-__slots__-are-implemented/
https://www.cnblogs.com/rainfd/p/slots.html
3 未实现和未实现异常
未实现和未实现的异常是两个东西他们的含义是:
- NotImplementedError:未实现异常类,是一个类。
- NotImplemented:未实现实例,是一个单值。
具体的区别看下面的例子:
class A:
def __init__(self,x):
self.data = x
def __add__(self, other):
return self.data + other.data
def __radd__(self, other):
return other + self.data
a = A(2)
print(1+a)
为什么是3呢。看下面的例子
class A:
def __init__(self,x):
self.data = x
def __add__(self, other):
try:
return self.data + other.data
except:
return NotImplemented
class B:
def __init__(self,name):
self.name = name
def __radd__(self, other):
return 'Handsome'
b = A(10)
daxin = B('daxin')
print(b+daxin) # Handsome
明白了吗?
- b+daxin,其实调用的是b.__add__(daxin)。
- 由于daxin没有data属性,所以一定会报异常。但是我们做了异常捕捉,最后会抛出NotImplemented(未实现)。
- 解释器不找到该值,并不会出发异常,而会转而调用daxin的__radd__方法。
所以:
- NotImplementedError一般和raise连用,定义在抽象基类中,用于告诉实例,该方法没有实现。
- NotImplemented是个单值,一般在算数方法中告诉解释器,没有实现。解释器转而执行右边操作对象的radd方法。
4 Python的对象模型
在Python中,任何对象都有类型,可以使用type()或者__class__查看。但是类型也是对象及类对象,它也有自己的类型。下图为Python中的类型与继承关系:

所以新类型的缺省类型都是type(可以使用元类来改变)
- 特殊类型type是所有对象的缺省类型,也包括type自己。但它又是一个对象,因此从object继承。
- 特殊类型object是继承树的顶层,它是Python所有类型的最终基类。
也就是说:继承都来自object,类型都看type,type也是对象继承自object,object也有类型,是type,这俩又很特殊,type的类型是它自己,object没有基类。
28 - 生成器交互-__slots__-未实现异常的更多相关文章
- C#不用union,而是有更好的方式实现 .net自定义错误页面实现 .net自定义错误页面实现升级篇 .net捕捉全局未处理异常的3种方式 一款很不错的FLASH时种插件 关于c#中委托使用小结 WEB网站常见受攻击方式及解决办法 判断URL是否存在 提升高并发量服务器性能解决思路
C#不用union,而是有更好的方式实现 用过C/C++的人都知道有个union,特别好用,似乎char数组到short,int,float等的转换无所不能,也确实是能,并且用起来十分方便.那C# ...
- 第25章 SEH结构化异常处理_未处理异常及向量化异常
25.1 UnhandledExceptionFilter函数详解 25.1.1 BaseProcessStart伪代码(Kernel32内部) void BaseProcessStart(PVOID ...
- Xamarin.Android-捕获未处理异常(全局异常)
一.前言 android中如果出现了未处理的异常,程序会闪退,这是非常不好的用户体验,很多用户会因此卸载APP,因此未处理的异常是应该尽力避免的. 有些很难避免的异常(如:IO.网络等),应在代码中进 ...
- Asp.net 未处理异常
页面级捕获未处理异常 - Page 的 Error 事件 Protected Sub Page_Error(ByVal sender As Object, ByVal e As System.Even ...
- asp.net捕获全局未处理异常的几种方法
通过HttpModule来捕获未处理的异常[推荐] 首先需要定义一个HttpModule,并监听未处理异常,代码如下: public void Init(HttpApplication context ...
- 页面打开 抛出w3wp.exe 中发生未处理异常
页面打开 抛出w3wp.exe 中发生未处理异常
- asp.net 捕获全局未处理异常的几种方法
通过HttpModule来捕获未处理的异常[推荐] 首先需要定义一个HttpModule,并监听未处理异常,代码如下: public void Init(HttpApplication context ...
- JAVA基础知识之多线程——线程组和未处理异常
线程组 Java中的ThreadGroup类表示线程组,在创建新线程时,可以通过构造函数Thread(group...)来指定线程组. 线程组具有以下特征 如果没有显式指定线程组,则新线程属于默认线程 ...
- NET环境下的未处理异常(unhandled exception)的解决方案
NET环境下的未处理异常(unhandled exception )的解决方案 .Net 框架提供了非常强大的异常处理机制,同时对一些非托管代码很难控制的系统问题比如指针越界,内存泄漏等提供了很好的解 ...
随机推荐
- 【操作系统、UNIX环境编程】进程间通信
多个进程可以共享系统中的各种资源,但其中许多资源一次只能为一个进程使用,我们把一次仅允许一个进程使用的资源称为临界资源,许多物理设备都属于临界资源,如打印机等. Linux下进程间通信有如下几种方式: ...
- LoadRunner脚本参数化常见错误
错误代码:Error:missing newline in d:\loadrunner\username.dat 错误原因:场景设置不合理,参数数量不够,或者参数化文件有问题. 1)如果参数化文件反复 ...
- 秒杀多线程第八篇 经典线程同步 信号量Semaphore (续)
java semaphore实现: Semaphore当前在多线程环境下被扩放使用,操作系统的信号量是个很重要的概念,在进程控制方面都有应用.Java 并发库 的Semaphore 可以很轻松完成信号 ...
- QoS专题-第2期-QoS实现工具之MQC
QoS实现工具之MQC QoS技术可以对网络中报文进行分类处理,根据优先级提供不同的差分服务,如何实现这种差分服务呢?我们有一种强大的配置方法-模块化QoS命令行MQC(Modular QoS Com ...
- CF1093F Vasya and Array DP
题面 题面 \(\Delta\)题面有点问题,应该是数列中没有长度大于等于\(len\)的连续数字才是合法的. 题解 设\(f[i][j]\)表示DP到\(i\)位,以\(j\)为结尾的方案数, \( ...
- Alpha 冲刺 —— 十分之一
队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作,对多个目标检测及文字识别模型进行评估.实验,选取较 ...
- 模块(3)-使用__future__
使用__future__ Python的每个新版本都会增加一些新的功能,或者对原来的功能作一些改动.有些改动是不兼容旧版本的,也就是在当前版本运行正常的代码,到下一个版本运行就可能不正常了. 从Pyt ...
- CF1100E
i207M给的题 省选前-小题解合集 给定一张有向图,每条边有边权.你可以花费边权的代价反转一条边,使得原图中没有环.最小化反转的边权的最大值. 首先二分,然后考虑判定. 转化为有些边可以翻转,有些边 ...
- 同时装了Python3和Python2,怎么用pip?
问题:同时装了Python3和Python2,怎么用pip? Ubuntu13.04, 系统内同时装了Python3.3 和 2.7 用sudo apt-get install python-pip ...
- Kruskal-Wallis test
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录视频) https://study.163.com/course/introduction.htm?courseId=1005269003&u ...