目录html
生成器提供了一个send方法用于动态的和生成器对象进行交互。怎么理解的呢?看下面的例子:python
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同样能够推进生成器的运行。dom
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以上的代码在另外一个线程中,是否是就实现了不一样线程之间的切换?函数
字典为了提高查询效率,必须用空间换时间。通常来讲一个实例,属性多一点,都存储在字典中便于查询,问题不大,可是若是数百万个实例,那么字典占用的空间就很大了,那么是否能够把类的__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__时code
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__属性时:orm
访问实例属性时,会被映射到对应的类的描述器上(数据描述器),其内部为每一个实例构建了专门的对象存储。(具体实现是用偏移地址来记录描述器,经过公式能够直接计算出其在内存中的实际地址,经过直接访问内存得到。)htm
定义了__slots__时,指定的属性都变为了描述器。对象
换句话说:__slots__告诉解释器,实例的属性都叫什么,通常来讲,既然要节约内存,最好仍是使用元组比较好,一旦类提供了__slots__,就阻止实例产生__dict__来保存实例的属性。__slots__不影响子类,不会被继承,但若是父类没有实现__slots__方法,那么子类的就没法生效.blog
使用建议:为了正确使用__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
未实现和未实现的异常是两个东西他们的含义是:
具体的区别看下面的例子:
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
明白了吗?
因此:
在Python中,任何对象都有类型,可使用type()或者__class__查看。可是类型也是对象及类对象,它也有本身的类型。下图为Python中的类型与继承关系:
因此新类型的缺省类型都是type(可使用元类来改变)
也就是说:继承都来自object,类型都看type,type也是对象继承自object,object也有类型,是type,这俩又很特殊,type的类型是它本身,object没有基类。