内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

如何在Python中使用__slots__屬性-創(chuàng)新互聯(lián)

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

創(chuàng)新互聯(lián)建站主要從事網(wǎng)站建設(shè)、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)民樂,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575

python是動(dòng)態(tài)語言,它允許程序在執(zhí)行過程中動(dòng)態(tài)綁定屬性或者方法(使用MethodTpye)。

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

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

Student.name = ''
Student.set_score = set_score

而如果使用__slots__,它僅允許動(dòng)態(tài)綁定()里面有的屬性

例如,下面這樣會(huì)報(bào)錯(cuò)

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

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

但是我覺得很奇怪,僅有這一個(gè)作用嗎?于是我再查了其他資料,發(fā)現(xiàn)這個(gè)函數(shù)可以很可觀地節(jié)約內(nèi)存,下面來一起看看詳細(xì)的介紹吧。

__slots__允許我們聲明并限定類成員,并拒絕類創(chuàng)建__dict__和__weakref__屬性以節(jié)約內(nèi)存空間。

Python是動(dòng)態(tài)語言,對(duì)于普通的類,可以為類實(shí)例賦值任何屬性,這些屬性會(huì)存儲(chǔ)在__dict__中:

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

這樣的特性帶來兩個(gè)問題:

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

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

當(dāng)然,__slots__就能解決這兩個(gè)問題。通過__slots__屬性限定類屬性的創(chuàng)建:

>>> 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類實(shí)例已經(jīng)不能隨意創(chuàng)建不在__slots__定義內(nèi)的屬性gender,同時(shí)實(shí)例中也不再有__dict__結(jié)構(gòu)。

用法

繼承樹

__slots__在繼承中有兩種表現(xiàn):

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

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

以下面的父類為例:

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

創(chuàng)建一個(gè)子類不聲明__slots__,該類實(shí)例可以創(chuàng)建父類__slots__限定之外的屬性gender:

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

而創(chuàng)建一個(gè)聲明__slots__的子類,該類屬性則只能創(chuàng)建父類__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__本身已經(jīng)繼承自父類,無需重復(fù)聲明父類已聲明的屬性。例如上例,重復(fù)聲明會(huì)多占用內(nèi)存空間:

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

性能對(duì)比

我們?yōu)槭裁匆褂胈_slots__呢?

更快速地賦值屬性

參考Stack Overflow回答中給出的數(shù)據(jù):

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

得到測試結(jié)果為:

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

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

節(jié)約內(nèi)存空間

>>> 0.3664822799983085 / 0.2846834529991611
1.2873325658284342

關(guān)于如何在Python中使用__slots__屬性就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

文章題目:如何在Python中使用__slots__屬性-創(chuàng)新互聯(lián)
標(biāo)題鏈接:http://www.rwnh.cn/article42/dhheec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站營銷型網(wǎng)站建設(shè)、用戶體驗(yàn)網(wǎng)站建設(shè)、靜態(tài)網(wǎng)站云服務(wù)器

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
隆子县| 霍山县| 高清| 正镶白旗| 鹿泉市| 台中县| 宕昌县| 夹江县| 桐庐县| 白山市| 都匀市| 怀远县| 乳源| 桐柏县| 安康市| 宜良县| 楚雄市| 融水| 娄烦县| 洪湖市| 农安县| 平度市| 甘孜县| 宁武县| 高要市| 旌德县| 磐石市| 广汉市| 郎溪县| 洞头县| 广西| 益阳市| 义乌市| 乌鲁木齐县| 鹿泉市| 同德县| 巫山县| 濉溪县| 桃源县| 海晏县| 墨玉县|