国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Python屬性、方法和類管理系列之----__slots__屬性

2019-11-14 17:03:06
字體:
來源:轉載
供稿:網友

一句話說明

__slots__是用來限制實例的屬性的,__slots__可以規定實例是否應該有__dict__屬性;__slots__不能限制類的屬性。

只有__slots__列表內的這些變量名可賦值為實例屬性。

class A:    __slots__=['name']    def __init__(self):        self.name='js'        self.age=22a=A()

運行結果:

Traceback (most recent call last):  File "a.py", line 6, in <module>    a=A()  File "a.py", line 5, in __init__    self.age=22AttributeError: 'A' object has no attribute 'age'

__slots__只是限制實例,對類對象沒有影響

class A:    __slots__=['name','city']    age=22    def __init__(self):        self.name='js'a=A()PRint('A __slots__: ', A.__slots__)print('a __slots__: ', a.__slots__)print('A __dict__: ', A.__dict__)print('a __dict__: ', a.__dict__)

運行結果如下:

A __slots__:  ['name', 'city']a __slots__:  ['name', 'city']#事實上,所有定義在__slots__中的屬性都會放置在類的__dict__當中,即使沒有使用的屬性(city)也是如此。#而當實例需要取對象時,總是會先到類的__dict__中進行檢查,如果類的__dict__中的屬性是一個對象且該對象對屬性的讀取做了一些限制,那么就會直接影響到實例是否能夠調用該屬性。__slots__的工作原理是如此,后面介紹的描述符類亦是如此。#在類的__dict__中,也會存入__slots__屬性。A __dict__:  {'age': 22, '__init__': <function A.__init__ at 0x7f2ae9be67b8>, 'name': <member 'name' of 'A' objects>, 'city': <member 'city' of 'A' objects>, '__slots__': ['name', 'city'], '__module__': '__main__', '__doc__': None}#當我們試圖調用a.__dict__時,出現錯誤,因為該屬性沒有出現在__slots__中,所以禁止賦值或者訪問。Traceback (most recent call last):  File "a.py", line 10, in <module>    print('a __dict__: ', a.__dict__)AttributeError: 'A' object has no attribute '__dict__'

可以同時存在__slots__和__dict__嗎?

可以,如果把__dict__屬性存入__slots__中,那么就允許使用__dict__屬性了。
這時,如果所有__slots__中定義的屬性存在__slots__中,如果沒有定義的屬性,那么存在__dict__中,從而實現屬性的分別管理。
dir函數獲取所有定義在__slots____dict__中的屬性。或者通過list(getattr(X, 'dict', [])) + getattr(X, 'slots', [])來得到所有的屬性。

class A:    __slots__=('name','city','__dict__')    def __init__(self):        self.name='js'        self.age=22a=A()print('A __slots__: ', A.__slots__)print('a __slots__: ', a.__slots__)print('A __dict__: ', A.__dict__)print('a __dict__: ', a.__dict__)

運行結果如下:

A __slots__:  ('name', 'city', '__dict__')a __slots__:  ('name', 'city', '__dict__')#連__dict__都會保存在類的__dict__中,且屬性值是一個object。A __dict__:  {'city': <member 'city' of 'A' objects>, 'name': <member 'name' of 'A' objects>, '__module__': '__main__', '__doc__': None, '__init__': <function A.__init__ at 0x7f540bb787b8>, '__slots__': ('name', 'city', '__dict__'), '__dict__': <attribute '__dict__' of 'A' objects>}#由于現在age沒有出現在__slots__中,且允許存在__dict__,所以屬性age出現在實例本身的__dict__中。a __dict__:  {'age': 22}

如果子類中沒有__slots__,但是超類中有...

class Super:    __slots__=['name']    passclass Sub(Super):    def __init__(self):        self.name='js'        self.age=22a=Sub()print('Sub __slots__: ', Sub.__slots__)print('a __slots__: ', a.__slots__)print('Sub __dict__: ', Sub.__dict__)print('a __dict__: ', a.__dict__)

運行結果如下:

#順利繼承到了Super的__slots__屬性Sub __slots__:  ['name']a __slots__:  ['name']#此時Python用了大量的黑暗魔法,這時我們看到Sub的__dict__中居然出現了__dict__屬性,且值為特殊的對象,相當于Sub.__slots__=Super.__slots__+['__dict__'],從而實現如果在__slots__中出現的屬性存在__slots__中,沒有出現的存在Sub的實例的__dict__中。Sub __dict__:  {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Sub' objects>, '__weakref__': <attribute '__weakref__' of 'Sub' objects>, '__doc__': None, '__init__': <function Sub.__init__ at 0x7fc35f7036a8>}#我們確實看到了age存在了子類的實例的__dict__中。a __dict__:  {'age': 22}

如果子類和父類都有__slots__...

class Super:    __slots__=['name','age']class Sub(Super):    __slots__=['city']print('Sub __slots__: ', Sub.__slots__)print('Sub __dict__: ', Sub.__dict__)

運行結果如下:

#父類中的__slots__沒有對子類產生影響Sub __slots__:  ['city']#再次證明了上面的說法,如果一定需要父類的__slots__進行疊加,那么需要手動設置為__slots__=Super.__slots__ + ['city'],所以可以看出Python通過了大量的黑暗魔法,從而達到__slots__不具有常規的繼承特性。Sub __dict__:  {'__slots__': ['city'], '__module__': '__main__', 'city': <member 'city' of 'Sub' objects>, '__doc__': None}

如果一個子類繼承自一個沒有__slots__的超類...

如果一個子類繼承自一個沒有__slots的超類,那么超類的dict屬性總是可以訪問的,使得子類中的一個slots__無意義。
留給你自己驗證一下吧。

總結

  1. __slots__用來設計成對實例的__dict__的限制,只有__dict__出現在__slots__中,實例才會有__dict__屬性。
    否則,只有出現在__slots__中的屬性才可以被使用。
  2. Python特意設計成__slots__沒有常規的繼承特性,所以只有超類具有__slots__且其__dict__屬性沒有出現在其中,這時子類的__slots__才有意義,且子類的__slots__不繼承父類的__slots__

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 延吉市| 岱山县| 广东省| 东乡族自治县| 定边县| 庆阳市| 买车| 三台县| 五华县| 龙口市| 湘西| 靖安县| 萨迦县| 乐安县| 龙州县| 汉中市| 山东| 平利县| 建水县| 彭水| 青岛市| 睢宁县| 房产| 临沧市| 西林县| 高安市| 德格县| 客服| 金湖县| 囊谦县| 花莲市| 景德镇市| 绥棱县| 建平县| 吉安县| 姚安县| 绥中县| 淮北市| 铜梁县| 辽阳市| 宜宾县|