黄视频网站在线免费观看-黄视频网站在线看-黄视频网站在线观看-黄视频网站免费看-黄视频网站免费观看-黄视频网站免费

千鋒教育-做有情懷、有良心、有品質的職業教育機構

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領取全套視頻
千鋒教育

關注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術干貨  > Python之詳解__slots__

Python之詳解__slots__

來源:千鋒教育
發布人:xqq
時間: 2023-11-07 13:51:58 1699336318

這個__slots__關鍵字究竟是做什么的呢?

它主要有兩個功能,我們先來說第一個功能,就是限制用戶的使用。

我們都知道Python是一門非常靈活的動態語言,很多在其他語言看起來完全不能容忍的事情在Python當中是可行的,這也是Python的設計理念,為了靈活和代碼方便犧牲了效率。比如我們來看一個很簡單的例子,由于Python是動態語言,所以類的成員甚至可以在類創建好了之后動態創建。這在靜態語言當中是絕對不行的,我們只能調用類當中已有的屬性,是不能或者很難添加新屬性的。

比如這段代碼:

classExp:

def__init__(self):

self.a=None

self.b=None

if__name__=="__main__":

exp=Exp()

exp.c=3

print(exp.c)

我們定義了一個類叫做Exp,我們為它創建了a和b兩個成員。但是我們在使用的時候,對c成員進行了賦值。要知道Exp類當中是沒有成員c的,但是程序并不會報錯,我們這么運行了之后它會將c添加進這個實例當中。

從一方面來看,這當然非常靈活,但是另一方面,這也留下了隱患。如果用戶隨意添加屬性,可能會導致未知的問題,尤其在復雜的系統當中。所以有些時候為了嚴謹,我們會不希望用戶做這種動態的修改。__slots__正是用來做這個的。

我們把這個關鍵字加上,再來運行結果就不一樣了:

classExp:

__slots__=['a','b']

def__init__(self):

self.a=None

self.b=None

if__name__=="__main__":

exp=Exp()

exp.c=3

print(exp.c)

如果你運行這段代碼的話,你會得到一個報錯,提示你Exp這個對象當中并沒有c這個成員,也就是說我們只能運用__slots__這個關鍵字當中定義的成員,對于沒有定義的成員不能隨意創建,這樣就限制了用戶的使用。

雖然現在大部分人使用這個關鍵字都是報著這個目的,但是很遺憾的是,Python創建者的初衷其實并不是這個。這就談到了__slots__關鍵字的第二個作用,就是節省內存。

如果了解過Python底層的實現原理,你會發現在Python當中為每一個實例都創建了一個字典,就是大名鼎鼎的__dict__字典。正是因為背后有一個字典,所以我們才可以創造出原本不存在的成員,也才支持這樣動態的效果。我們可以人工地調用這個字典輸出其中的內容,我們在加上__slots__關鍵字之前,輸出的結果是這樣的:

{'a':None,'b':None}

但是加上了這個關鍵字之后,會得到一個報錯,會告訴你Exp這個對象當中沒有__dict__這個成員。原因很簡單,因為使用dict來維護實例,會消耗大量的內存,額外存儲了許多數據,而使用__slots__之后,Python內部將不再為實例創建一個字典來維護,而是會使用一個固定大小的數組,這樣就節省了大量的空間。這個節省可不是一點半點,一般可以節省一半以上。也就是說犧牲了一定的靈活性,保證了性能。這一點也是__slots__這個關鍵字設計的初衷,但是現在很多人都用錯了地方。

property這個關鍵字在的文章當中曾經提到過,不過很不好意思的是,由于之前寫文章的時候對它的了解還很有限,導致一些闡述存在一些謬誤,所以這里再提一下這個關鍵字的運用作為彌補。

property可以幫我們綁定類當中一些屬性的賦值和獲取,也就是get和set。我們來看個例子:

classExp:

def__init__(self,param):

self.param=param

@property

defparam(self):

returnself._param

@param.setter

defparam(self,value):

self._param=value

這里的property注解會在我們調用.param的時候被執行,而param.setter會在我們為param這個屬性賦值的時候被執行。所以你可能會奇怪,為什么我們在__init__方法當中初始化的時候用的是self.param=param而不是self._param=param,這是因為我們在執行前者的時候,Python一樣會調用@param.setter這個注解,所以我們沒有必要寫成后者的形式。當然你也可以這么寫,不過兩者是完全等價的。

作為一個前Java程序員為類當中所有變量加上get和set方法幾乎成了政治正確,所以我特別喜歡為類當中所有的屬性加上property。但是這是不對的,加上property是非常耗時的,所以如非必要不要這么做,我們直接調用來進行賦值就好了,如果有必要,我們可以手動寫上get和set方法。那么問題來了,既然不是為了規范,那么我們又為什么要用到property呢?

答案很簡單,為了校驗變量類型。

由于Python是動態語言,并且是隱式類型的,所以我們拿到變量的時候并不知道它究竟是什么類型,也不知道用戶為給它賦值成什么類型。所以在一些情況下我們可能會希望做好限制,告訴用戶只能將這個變量賦值成這個類型,否則就會報錯。通過使用property,我們可以很方便地做到這點。

classExp:

def__init__(self,param):

self.param=param

@property

defparam(self):

returnself._param

@param.setter

defparam(self,value):

ifnotisinstance(value,str):

raiseTypeError('Wantastring')

self._param=value

除此之外,property還有一個用法是代替函數。舉個例子:

classExp:

def__init__(self,param):

self.param=param

@property

defparam(self):

returnself._param

@param.setter

defparam(self,value):

ifnotisinstance(value,str):

raiseTypeError('Wantastring')

self._param=value

@property

defhello(self):

return'hello'+self.param

這樣我們就可以通過.hello來代替調用一個函數,這樣做其實是一種動態計算。hello的結果并沒有被存儲起來,之后當我們調用的時候才會執行,在一些場景下這樣做會非常方便。

命名規范最后我們來看下Python對象當中的命名規范,在之前的文章當中我們曾經說過,在Python當中沒有對public和private的字段做區分,所有的字段都是public的,也就是說用戶可以拿到類當中所有的字段和方法。為了規范,程序員們約定俗成,決定所有加了下劃線的方法和變量都看成是private的,即使我們能調用,但是一般情況下我們也不這么干。

所以我們通常會寫兩個方法,一個是公開的接口,一個是內部的實現。我們調用的時候只調用公開的接口,公開的接口再去調用內部的實現。這在Python當中已經成了慣例,因為我們在調用內部方法的時候,往往還會傳入一些內部的參數。

我們來看個簡單的例子:

classExpA:

def__init__(self):

pass

defpublic_func(self):

self._private_func()

def_private_func(self):

print('privateExpA')

if__name__=="__main__":

exp=ExpA()

exp.public_func()

除了_之外我們經常還會看到一些兩個下劃線的變量和方法,那么它們之間又有什么區別呢?

為了回答這個問題,我們來看下面這個例子:

classExpA:

def__init__(self):

pass

defpublic_func(self):

self.__private_func()

def__private_func(self):

print('privateExpA')

classExpB(ExpA):

def__init__(self):

pass

defpublic_func(self):

self.__private_func()

def__private_func(self):

print('privateExpB')

if__name__=="__main__":

exp=ExpB()

exp.public_func()

exp._ExpB__private_func()

exp._ExpA__private_func()

請問最后會輸出什么?

我們試一下就知道,第一行輸出的是privateExpB,這個沒有問題。但是后面兩個是什么?

后面兩個就是__private_func,只不過系統自動將它重新命名了。重新命名的原因也很簡單,因為Python禁止加了兩個下劃線的方法被子類覆蓋。所以這兩者的區別就在這里,它們都被認為是private的方法和屬性,但是一個下劃線允許子類覆蓋,而兩個下劃線不行。所以如果我們在開發的時候希望我們某一個方法不會被子類覆蓋,那么我們就需要加上兩個下劃線。

最后,我們來看一個小問題。在C++當中當我們的變量名和系統的關鍵字沖突的時候,我們往往會在變量前面加上一個_來作為區分。但是由于Python當中下劃線被賦予了含義,所以我們不能這么干,那么當變量沖突的時候應該怎么辦呢?答案也很簡單,我們可以把下劃線加在后面,比如lambda_。

以上內容為大家介紹了Python之詳解__slots__,希望對大家有所幫助,如果想要了解更多Python相關知識,請關注IT培訓機構:千鋒教育。

tags: python培訓
聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。
10年以上業內強師集結,手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內將與您1V1溝通
免費領取
今日已有369人領取成功
劉同學 138****2860 剛剛成功領取
王同學 131****2015 剛剛成功領取
張同學 133****4652 剛剛成功領取
李同學 135****8607 剛剛成功領取
楊同學 132****5667 剛剛成功領取
岳同學 134****6652 剛剛成功領取
梁同學 157****2950 剛剛成功領取
劉同學 189****1015 剛剛成功領取
張同學 155****4678 剛剛成功領取
鄒同學 139****2907 剛剛成功領取
董同學 138****2867 剛剛成功領取
周同學 136****3602 剛剛成功領取
相關推薦HOT
天天做日日爱夜夜爽| 日韩av片免费播放| 天天做人人爱夜夜爽2020| 一级毛片视频在线观看| 国产激情视频在线观看| 国产视频一区在线| 香蕉视频久久| 欧美激情在线精品video| 国产伦理精品| 台湾美女古装一级毛片| 久久精品欧美一区二区| 午夜在线亚洲| 日韩综合| 天天做日日爱夜夜爽| 美女免费精品高清毛片在线视| 97视频免费在线观看| 国产一级生活片| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 午夜在线观看视频免费 成人| 国产一区二区精品久久| 成人在激情在线视频| 欧美另类videosbestsex久久 | 日韩综合| 色综合久久天天综合| 一级片免费在线观看视频| 欧美激情一区二区三区视频 | 韩国毛片免费| 精品久久久久久中文字幕2017| 国产91精品系列在线观看| 成人在激情在线视频| 日韩免费片| 欧美α片无限看在线观看免费| 欧美大片一区| 欧美另类videosbestsex久久 | 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 国产亚洲精品aaa大片| 国产伦理精品| 你懂的日韩| 美国一区二区三区| 天天色成人网| 成人免费福利片在线观看| 天天色成人网| 免费的黄色小视频| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 精品视频一区二区三区| 国产伦久视频免费观看视频| 精品久久久久久中文字幕一区| 欧美大片aaaa一级毛片| 国产成人精品综合久久久| 国产a视频| 国产91精品露脸国语对白| 黄色福利片| 日韩av成人| 日韩专区亚洲综合久久| 欧美激情影院| 精品国产香蕉在线播出| 亚洲天堂在线播放| 国产一区二区精品久| 国产成人啪精品视频免费软件| 国产美女在线一区二区三区| 日韩中文字幕在线播放| 999久久久免费精品国产牛牛| 日韩免费片| 亚洲女初尝黑人巨高清在线观看| 午夜家庭影院| 国产麻豆精品免费视频| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 欧美爱色| 日本特黄特黄aaaaa大片| 国产麻豆精品高清在线播放| 精品视频在线观看视频免费视频 | 999精品视频在线| 欧美1区2区3区| 精品视频在线看| 久久久久久久男人的天堂| 亚洲精品中文一区不卡| 国产伦精品一区三区视频| 久久精品免视看国产明星 | 成人高清视频在线观看| 日韩中文字幕在线亚洲一区| 夜夜操网| 亚洲 激情| 国产国产人免费视频成69堂| 九九干| 亚飞与亚基在线观看| 一级毛片视频播放| 亚州视频一区二区| 九九九国产| 一 级 黄 中国色 片| 香蕉视频久久| 精品视频在线观看免费| 精品国产一区二区三区久| 韩国三级一区| 国产高清在线精品一区二区| 国产国语对白一级毛片| 可以免费看毛片的网站| 国产视频一区二区三区四区| 日韩中文字幕在线播放| 青青青草视频在线观看| 香蕉视频久久| 亚洲天堂免费| 亚洲爆爽| 国产a免费观看| 成人免费一级纶理片 | 国产成人精品综合在线| 欧美日本免费| 免费毛片基地| 免费一级生活片| 久久成人综合网| 欧美18性精品| 日本免费看视频| 国产国语在线播放视频| 免费毛片基地| 国产原创视频在线| 久久精品大片| 日本特黄一级| 国产国产人免费视频成69堂| 欧美激情在线精品video| 国产综合91天堂亚洲国产| 国产高清视频免费观看| 四虎影视久久久免费| 可以免费看污视频的网站| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 九九精品久久久久久久久| 999久久久免费精品国产牛牛| 99久久精品国产国产毛片| 麻豆网站在线看| 在线观看导航| 中文字幕一区二区三区精彩视频| 日韩免费在线视频| 欧美另类videosbestsex久久 | 可以在线看黄的网站| 日日爽天天| 黄色短视屏| 韩国三级视频网站| 欧美激情一区二区三区视频 | 精品视频在线观看一区二区| 精品国产一级毛片| 美国一区二区三区| a级精品九九九大片免费看| 日韩中文字幕在线播放| 一a一级片| 国产成人欧美一区二区三区的| 国产精品1024在线永久免费 | 日日日夜夜操| 99热精品在线| 欧美激情一区二区三区在线播放| 国产不卡在线看| 精品视频在线看| 日本在线www| 国产欧美精品| 欧美一级视| 青青久久国产成人免费网站| 黄视频网站免费观看| 精品视频在线看 | 欧美激情伊人| 午夜欧美成人香蕉剧场| 成人av在线播放| 久草免费资源| 香蕉视频一级| 一 级 黄 中国色 片| 午夜在线亚洲男人午在线| 黄视频网站在线观看| 午夜欧美成人久久久久久| 国产麻豆精品视频| 成人在激情在线视频| 国产麻豆精品免费密入口| 精品国产一区二区三区免费| 国产网站免费视频| 成人免费福利片在线观看| 999精品影视在线观看| 国产精品12| 国产亚洲免费观看| 欧美a级v片不卡在线观看| 日韩综合| 国产网站免费视频| 日韩在线观看免费完整版视频| 国产一区二区精品久| 日韩专区亚洲综合久久| 色综合久久久久综合体桃花网| 欧美激情一区二区三区在线| 国产视频一区二区三区四区| 黄视频网站免费看| 99热精品在线| 国产不卡高清| 国产福利免费观看| 99色吧| 黄视频网站免费观看| 免费毛片基地| 欧美日本免费| 日韩avdvd| 国产成人啪精品| 精品视频在线观看一区二区| 国产欧美精品午夜在线播放| 香蕉视频亚洲一级| 欧美大片a一级毛片视频| 国产91精品系列在线观看| 999精品在线| 日本在线播放一区| 亚洲精品影院|