中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何在Python中使用__slots__屬性

發布時間:2021-03-26 16:24:04 來源:億速云 閱讀:193 作者:Leah 欄目:開發技術

這篇文章給大家介紹如何在Python中使用__slots__屬性,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

python是動態語言,它允許程序在執行過程中動態綁定屬性或者方法(使用MethodTpye)。

某個實例在執行過程中綁定的屬性跟方法,僅在該實例中有效,其他同類實例是沒有的。

可以通過給class綁定屬性/方法,來給所有實例綁定屬性/方法:

Student.name = ''
Student.set_score = set_score

而如果使用__slots__,它僅允許動態綁定()里面有的屬性

例如,下面這樣會報錯

class Student():
__slots__ = ('name', 'age')

S1 = Student()
S1.name = 'Jack' # ok!
S1.score = 123 # error!

但是我覺得很奇怪,僅有這一個作用嗎?于是我再查了其他資料,發現這個函數可以很可觀地節約內存,下面來一起看看詳細的介紹吧。

__slots__允許我們聲明并限定類成員,并拒絕類創建__dict__和__weakref__屬性以節約內存空間。

Python是動態語言,對于普通的類,可以為類實例賦值任何屬性,這些屬性會存儲在__dict__中:

>>> class Student(object):
... pass
... 
>>> Abey = Student()
>>> Abey.name = 'Abey'
>>> Abey.__dict__
{'name': 'Abey'}

這樣的特性帶來兩個問題:

  • 數據通過字典(Hash)存儲所占用的空間較大

  • 如何禁止隨意生成類屬性

當然,__slots__就能解決這兩個問題。通過__slots__屬性限定類屬性的創建:

>>> class Student(object):
... __slots__ = ('name', 'age')
... 
>>> Abey = Student()
>>> Abey.name = 'Abey'
>>> Abey.gender = 'Female'
Traceback (most recent call last):
 File "<input>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'gender'
>>> Abey.__dict__
Traceback (most recent call last):
 File "<input>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__dict__'

可以看到,在定義了__slots__變量后,Student類實例已經不能隨意創建不在__slots__定義內的屬性gender,同時實例中也不再有__dict__結構。

用法

繼承樹

__slots__在繼承中有兩種表現:

  • 子類未聲明__slots__時,不繼承父類的__slots__,即此時子類實例可以隨意賦值屬性

  • 子類聲明__slots__時,繼承父類的__slots__,即此時子類的__slots__為其自身+父類的__slots__

以下面的父類為例:

>>> class Student(object):
... __slots__ = ('name', 'age')
...

創建一個子類不聲明__slots__,該類實例可以創建父類__slots__限定之外的屬性gender:

>>> class SubStudent(Student):
... pass
... 
>>> Bob = SubStudent()
>>> Bob.gender = 'Male'
>>> Bob.__dict__
{'gender': 'Male'}

而創建一個聲明__slots__的子類,該類屬性則只能創建父類__slots__+自身__slots__限定的屬性:

>>> class SubStudent2(Student):
... __slots__ = 'gender'
... 
>>> Cathy = SubStudent2()
>>> Cathy.gender = 'Female'
>>> Cathy.name = 'Cathy'
>>> Cathy.teacher = 'Mrs. Wang'
Traceback (most recent call last):
 File "<input>", line 1, in <module>
AttributeError: 'SubStudent2' object has no attribute 'teacher'

注意:子類的__slots__本身已經繼承自父類,無需重復聲明父類已聲明的屬性。例如上例,重復聲明會多占用內存空間:

>>> class SubStudent3(Student):
... __slots__ = ('name', 'age', 'gender')
... 
>>> from sys import getsizeof
>>> getsizeof(Student()), getsizeof(SubStudent2()), getsizeof(SubStudent3())
(56, 64, 80)

性能對比

我們為什么要使用__slots__呢?

更快速地賦值屬性

參考Stack Overflow回答中給出的數據:

import timeit

class Foo(object): __slots__ = 'foo',

class Bar(object): pass

slotted = Foo()
not_slotted = Bar()

def get_set_delete_fn(obj):
 def get_set_delete():
 obj.foo = 'foo'
 obj.foo
 del obj.foo
 return get_set_delete

得到測試結果為:

>>> min(timeit.repeat(get_set_delete_fn(slotted)))
0.2846834529991611
>>> min(timeit.repeat(get_set_delete_fn(not_slotted)))
0.3664822799983085

可以看到,在相同的環境(Ubuntu)下,slots為Python3.5帶來了接近30%的賦值速度提升:

節約內存空間

>>> 0.3664822799983085 / 0.2846834529991611
1.2873325658284342

關于如何在Python中使用__slots__屬性就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

花垣县| 原阳县| 任丘市| 龙州县| 澄江县| 兖州市| 栾川县| 襄汾县| 桐梓县| 白城市| 阿荣旗| 夹江县| 怀柔区| 万载县| 贵定县| 大安市| 沾化县| 景洪市| 贵德县| 灵石县| 惠安县| 武夷山市| 永昌县| 循化| 白朗县| 布拖县| 龙山县| 伊金霍洛旗| 鄄城县| 姜堰市| 客服| 绿春县| 临沂市| 黄浦区| 北安市| 灵丘县| 金昌市| 连城县| 二手房| 揭西县| 买车|