鍍金池/ 教程/ Python/ slots 魔法
基礎(chǔ)
itertools
HTTP 服務(wù)
hashlib
閉包
文件和目錄
單元測試
使用 @property
標(biāo)準(zhǔn)模塊
陌生的 metaclass
Base64
進(jìn)程、線程和協(xié)程
讀寫二進(jìn)制文件
匿名函數(shù)
輸入和輸出
Click
元組
字符編碼
partial 函數(shù)
參考資料
collections
協(xié)程
類和實(shí)例
Python 之旅
定制類和魔法方法
常用數(shù)據(jù)類型
繼承和多態(tài)
ThreadLocal
HTTP 協(xié)議簡介
Requests 庫的使用
讀寫文本文件
列表
os 模塊
迭代器 (Iterator)
正則表達(dá)式
集合
上下文管理器
異常處理
你不知道的 super
定義函數(shù)
datetime
資源推薦
字典
slots 魔法
hmac
第三方模塊
進(jìn)程
類方法和靜態(tài)方法
函數(shù)參數(shù)
高階函數(shù)
函數(shù)
re 模塊
高級(jí)特性
線程
argparse
生成器
結(jié)束語
字符串
map/reduce/filter
函數(shù)式編程
Celery
裝飾器

slots 魔法

在 Python 中,我們?cè)诙x類的時(shí)候可以定義屬性和方法。當(dāng)我們創(chuàng)建了一個(gè)類的實(shí)例后,我們還可以給該實(shí)例綁定任意新的屬性和方法。

看下面一個(gè)簡單的例子:

class Point(object):    
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

>>> p = Point(3, 4)
>>> p.z = 5    # 綁定了一個(gè)新的屬性
>>> p.z
5
>>> p.__dict__
{'x': 3, 'y': 4, 'z': 5}

在上面,我們創(chuàng)建了實(shí)例 p 之后,給它綁定了一個(gè)新的屬性 z,這種動(dòng)態(tài)綁定的功能雖然很有用,但它的代價(jià)是消耗了更多的內(nèi)存。

因此,為了不浪費(fèi)內(nèi)存,可以使用 __slots__ 來告訴 Python 只給一個(gè)固定集合的屬性分配空間,對(duì)上面的代碼做一點(diǎn)改進(jìn),如下:

class Point(object):
    __slots__ = ('x', 'y')       # 只允許使用 x 和 y

    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

上面,我們給 __slots__ 設(shè)置了一個(gè)元組,來限制類能添加的屬性?,F(xiàn)在,如果我們想綁定一個(gè)新的屬性,比如 z,就會(huì)出錯(cuò)了,如下:

>>> p = Point(3, 4)
>>> p.z = 5
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-648-625ed954d865> in <module>()
----> 1 p.z = 5

AttributeError: 'Point' object has no attribute 'z'

使用 __slots__ 有一點(diǎn)需要注意的是,__slots__ 設(shè)置的屬性僅對(duì)當(dāng)前類有效,對(duì)繼承的子類不起效,除非子類也定義了 __slots__,這樣,子類允許定義的屬性就是自身的 slots 加上父類的 slots。

小結(jié)

  • slots 魔法:限定允許綁定的屬性.
  • __slots__ 設(shè)置的屬性僅對(duì)當(dāng)前類有效,對(duì)繼承的子類不起效,除非子類也定義了 slots,這樣,子類允許定義的屬性就是自身的 slots 加上父類的 slots。

參考資料

上一篇:基礎(chǔ)下一篇:參考資料