目錄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沒有基類。