寫在之前
圍繞類的話題,說是說不完的,僅在特殊方法,除了我們在前面遇到過的 __init__(),__new__(),__str__() 等之外還有很多。雖然它們只是在某些特殊的場景中才會用到,但是學會它們卻可以成為你熟悉這門語言路上的鋪路石。
所以我會在試圖介紹一些「黑魔法」,讓大家多多感受一下 python 的魅力所在,俗話說「藝多不壓身」就是這個道理了。
記憶體優化
首先先讓我們從複習前面的類屬性和例項屬性的知識來引出另乙個特殊方法:
>>> class sample:
... name = 'rocky'
>>> sample.__dict__
>>> sample.name
'rocky'
同樣,如果我們建立了例項,每個例項也有乙個 __dict__ 屬性,它裡面就是當前的例項屬性:
>>> a = sample()
>>> a.__dict__
>>> a.age = 23
>>> a.__dict__
上面的操作可以看出,當例項剛剛建立的時候,__dict__ 是空的,只有建立了例項屬性以後,它才包含其內容。例項的 __dict__ 和類的 __dict__ 是有所區別的,即例項屬性和類屬性是不同的。
從理論上來說,我們可以根據乙個類建立無數的例項,新建乙個例項以後,又建立了乙個新的 __dict__,這將是乙個很可怕的事情,雖然每個 __dict__ 所佔的記憶體空間很小,當然這件事事實上是不會出現的。但是程式不能建立在這種不可靠的猜測的基礎上,程式要對過程有明確的控制。
所以就要有一種方法能夠控制 __dict__,於是「__slots__」應運而生。
>>> class nature:
... __slots__ = ('tree','flower')
>>> dir(nature)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'flower', 'tree']
我們仔細來看 dir() 的結果,發現 __dict__ 屬性沒有了,也就是說 __slots__ 把 __dict__ 擠出去了,它進入了類的屬性。
>>> nature.__slots__
('tree', 'flower')
從這裡可以看出,類 nature 有且僅有兩個屬性。從類的角度來看,其類屬性只有這兩個;從例項的角度來看,其實例屬性也只有這兩個。
>>> nature.tree = 'liushu'
>>> nature.tree
'liushu'
>>> nature.tree = 'lishu'
>>> nature.tree
'lishu'
通過類可以對屬性進行賦值和修改,這個似乎和以前的類屬性沒有什麼區別,別著急,繼續往下看就看到區別了:
>>> x = nature()
>>> x.__slots__
('tree', 'flower')
>>> y = nature()
>>> y.__slots__
('tree', 'flower')
>>> id(x.__slots__)
>>> id(y.__slots__)
你看,例項化以後,例項的 __slots__ 和類的 __slots__ 完全一樣,這跟前面的 __dict__ 大不一樣了。並且我們建立了兩個例項,結果發現兩個例項的 __slots__ 在記憶體中居然是乙個,或者可以說是增加例項時 __slots__ 並不增加。
>>> x.tree
'lishu'
>>> y.tree
'lishu'
既然類屬性已經賦值,那麼通過任何乙個例項屬性都能得到同樣的值,不過這時候不能通過例項修改此屬性的值。
>>> x.tree = 'taoshu'
traceback (most recent call last):
file "", line 1, in
attributeerror: 'nature' object attribute 'tree' is read-only
對例項屬性來說,類的靜態資料是唯讀的,不能修改,只有通過類屬性才能修改。但對於尚未賦值的屬性,能夠通過例項賦值。
>>> x.flower = 'rose'
>>> x.flower
'rose'
>>> x.flower = 'moli'
顯然通過例項操作的屬性,也能夠通過例項修改,但是例項屬性的值並不能夠修改類屬性的值
nature.flower
由上面可以看出,例項屬性的值並沒有傳回給類屬性,也可以理解為新建了乙個同名字的例項屬性,如果再給類屬性賦值的話,則會像下面一樣:
>>> nature.flower = 'huaihua'
>>> x.flower
'huaihua'
類屬性對例項屬性具有決定作用,對例項而言,通過類所定義的屬性都是唯讀的。
__slots__ 已經把例項屬性牢牢的看管起來,只能是指定的屬性,如果想要增加屬性的話,只能通過類屬性來實現,所以 __slots__ 的乙個重要作用就是優化了記憶體。
寫在之後
當然了,__slots__ 還能加快屬性載入速度,這個不是本文的重點,所以不做過多的介紹,感興趣的可以去 google 一下。
今天的文章就到這裡啦,明天講一下「屬性攔截」,又是新的一周,燥起來!
the end。
Spark調優詳解
調優概述 spark效能調優 1 spark效能調優 2 調優主要方法 開發調優 資料本地化調優 資料傾斜調優 shuffle調優 資源調優 jvm調優 spark中對於乙個rdd的執行多次運算元的預設原理是這樣的 每次你對乙個rdd執行乙個運算元的操作的時候,都會從源頭計算一遍 因為rdd是根據f...
Hive 調優詳解
在舊版本的 hive 中,hive default.xml.template檔案中hive.fetch.task.conversion預設是minimal,修改為more後,全域性查詢 字段查詢 limit查詢等都會直接執行而不會執行 mapreduce.新版本的 hive fetch 的預設值已改...
Linux記憶體 效能調優
記憶體是影響linux效能的主要因素之一,記憶體資源的充足與否直接影響應用系統的使用效能。free命令 監控linux記憶體使用狀況。由上圖可知,空閒記憶體是free buffers cached 155mb 一般來說如果空閒記憶體 物理記憶體 70 記憶體效能優 如果小於20 則效能差,需要新增記...