溫馨提示×

溫馨提示×

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

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

Python中的高階概念屬性知識點有哪些

發(fā)布時間:2021-10-27 10:44:36 來源:億速云 閱讀:119 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“Python中的高階概念屬性知識點有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Python中的高階概念屬性知識點有哪些”吧!

1.類屬性

為了更好地管理項目中的數(shù)據(jù),我們經(jīng)常需要創(chuàng)建自定義類。在Python中,類也是對象,這意味著它們可以有自己的屬性。讓我們看一個例子。

>>> class Dog: ...     genus = "Canis" ...     family = "Canidae" ...>>> Dog.genus'Canis' >>> Dog.family'Canidae' >>> dir(Dog)['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__',   '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__',   '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',   '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',   'family', 'genus']

如上所示,我們聲明了一個名為Dog的類。因為所有的狗都屬于犬類屬和犬科家族,所以我們創(chuàng)建了兩個類屬性,分別命名為屬和科來存儲這兩條信息。如您所見,我們可以直接使用類來訪問這些屬性。我們可以使用函數(shù)dir來顯示狗的屬性列表,其中包括家族和屬。

這些定義為類級別的屬性稱為類屬性,類可以直接檢索它們。但是,與其他OOP語言不同,Python中的實例對象也可以直接訪問這些類屬性,如下面的代碼片段所示。

>>> Dog().genus 'Canis' '>>> Dog().family 'Canidae'

2.實例屬性

通過自定義類,我們還可以為實例對象設(shè)置屬性。這些屬性稱為實例屬性,這意味著它們是特定于實例的數(shù)據(jù)。讓我們繼續(xù)狗類。

>>> class Dog: ...     genus = "Canis" ...     family = "Canidae" ......     def __init__(self, breed, name): ...         self.breed = breed...         self.name = name...

在上面的代碼中,我們定義了__init__函數(shù),它將作為創(chuàng)建一個新的Dog實例的構(gòu)造方法。第一個參數(shù)self引用了我們正在創(chuàng)建的實例。在實例化期間(即創(chuàng)建新實例),我們將為新實例對象分配品種和名稱信息,這些屬性將成為實例特征的一部分,如下所示。

>>> dog = Dog("Rottweiler", "Ada") >>> dog.name'Ada' >>> dog.breed'Rottweiler'

需要注意的一點是,我們可以為具有與class屬性相同的屬性的實例賦值。在這種情況下,當(dāng)您檢索實例的這個屬性時,將不會檢索class屬性。換句話說,當(dāng)您使用一個實例對象來檢索class屬性時,Python將首先檢查實例本身是否有一個用相同名稱設(shè)置的屬性。如果沒有,Python將使用class屬性作為回退。此外,設(shè)置一個實例的屬性不會影響同名類的屬性。讓我們在下面的代碼片段中看看這些特征。

>>> dog.genus = "Felis" >>> dog.genus'Felis' >>> Dog('Poodle', 'Cutie').genus 'Canis'

3.函數(shù)作為屬性

在Python中,一切都是對象,前面我已經(jīng)提到類是對象。此外,函數(shù)是Python對象。在類中,我們可以定義函數(shù),通常稱為方法。根據(jù)使用這些函數(shù)的方式,我們可以將它們進(jìn)一步分類為類方法、靜態(tài)方法和實例方法。在這里,理解這些差異并不是必須的。

盡管某些OOP語言將屬性(或?qū)傩?和函數(shù)視為不同的實體,但Python將這些方法(函數(shù))視為類的屬性——與我們前面定義的類屬性沒有太大區(qū)別。讓我們用上面提到的三種方法來更新Dog類:類方法、靜態(tài)方法和實例方法,如下所示。

>>> class Dog: ...     genus = "Canis" ...     family = "Canidae" ......     def __init__(self, breed, name): ...         self.breed = breed...         self.name = name......     @classmethod...     def from_tag(cls, tag_info): ...         breed = tag_info["breed"] ...         name = tag_info["name"] ...         return cls(breed, name) ......     @staticmethod...     def can_bark(): ...         print("Yes. All dogs can bark.") ......     def bark(self): ...         print("The dog is barking.") ...

對于更新后的類,我們可以使用函數(shù)dir檢查類的屬性列表。如下所示,類方法和靜態(tài)方法都包含在列表中。

>>> dir(Dog) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__',  '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__',  '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',  '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',  'bark', 'can_bark', 'family', 'from_tag', 'genus']

然而,有一件事可能會讓一些人感到驚訝,那就是該列表中包含了實例方法bark。我們知道,實例方法是那些由實例對象調(diào)用的函數(shù),因此有些人可能認(rèn)為這些實例方法應(yīng)該綁定到所有單獨的實例。然而,在Python中卻不是這樣。在解釋實例方法如何工作之前,讓我們先看看下面的代碼。

>>> dog = Dog("Rottweiler", "Ada") >>> dog.bark()The dog is barking. >>> Dog.bark(dog)The dog is barking.

如上所示,我們首先創(chuàng)建了Dog類的一個實例。與其他OOP語言一樣,實例對象可以直接調(diào)用實例方法bark。然而,Python與其他語言的不同之處在于,實例方法的調(diào)用是通過類來操作的,通過傳遞實例作為參數(shù)來調(diào)用定義的函數(shù)(即,dog  .bark(dog))。換句話說,instance.inst_method()在本質(zhì)上與Python中的Class.inst_method(instance)相同。

之所以可以這樣做,是因為Dog類“擁有”實例方法,這是一種節(jié)省內(nèi)存的機(jī)制,因為Python不需要為每個實例對象創(chuàng)建單獨的函數(shù)副本。相反,當(dāng)一個實例調(diào)用一個實例方法時,Python將調(diào)用委托給類,該類將通過傳遞實例調(diào)用相應(yīng)的函數(shù)(它將被設(shè)置為已定義函數(shù)中的self參數(shù))。

4.私有屬性

如果您有OOP的經(jīng)驗,就不應(yīng)該不熟悉訪問修飾符的存在,比如public、private和protected。這些修飾符限制了可以訪問修改的屬性和函數(shù)的范圍。然而,您很少在Python中聽到這樣的討論。實際上,如果借用OOP中的術(shù)語,所有Python屬性都是公共的。如上所示,在類和實例可以訪問的地方,類和實例屬性都可以自由訪問。因此,嚴(yán)格地說,Python中沒有真正的私有或受保護(hù)的屬性(后面將討論)。我們只是類比地使用這些術(shù)語,以便來自其他OOP背景的程序員更容易理解相關(guān)的編碼約定(是的,只是一種約定,沒有作為真正的訪問控制加以加強(qiáng))。

讓我們首先討論一下如何在Python中定義“私有”屬性。慣例是用兩個前導(dǎo)下劃線命名這些屬性,并且不超過一個后引下劃線。考慮下面更新過的Dog類的示例—為了簡單起見,我們省略了前面定義的其他屬性。

>>> class Dog: ...     def __init__(self, breed, name): ...         self.breed = breed...         self.name = name...         self.__tag = f"{name} | {breed}" ... >>> dog = Dog("Rottweiler", "Ada") >>> dog.name'Ada' >>> dog.__tagTraceback (most recent call last):  File "<stdin>", line 1, in <module> AttributeError: 'Dog' object has no attribute '__tag'

在上面的更新之后,Dog實例將擁有一個名為tag的私有屬性,正如其名稱所示。實例對象仍然可以像以前一樣訪問它的其他屬性(例如,名稱)。然而,實例不能訪問私有屬性剩余的標(biāo)記,這可能是我們所期望的。實際上,這種對訪問這些屬性的限制正是它們被稱為“私有”屬性的原因。但它是怎么發(fā)生的,在引擎蓋下?畢竟,我前面提到過,所有Python屬性在默認(rèn)情況下都是公共的。下面將向您展示Python如何實現(xiàn)“私有”屬性。

>>> dog.__dict__ {'breed': 'Rottweiler', 'name': 'Ada', '_Dog__tag': 'Ada | Rottweiler'} >>> dog._Dog__tag'Ada | Rottweiler'

__dict__特殊方法(也稱為dunder方法,在名稱前后都有雙下劃線)能夠顯示對象的字典表示。具體來說,字典中的鍵-值對是對象的屬性及其值。正如我們所看到的,除了bread和name屬性之外,還有一個名為_dog__tag標(biāo)記的屬性。這個屬性正是私有屬性__tag通過一個稱為mangling的過程與對象關(guān)聯(lián)的方式。

具體來說,mangling或name  mangling是使用_ClassName作為私有屬性的前綴,這樣我們就人為地創(chuàng)建了對這些“私有”屬性的訪問限制。但是,如果我們確實想檢索任何私有屬性,我們?nèi)匀豢梢允褂帽黄茐牡拿Q訪問它,就像我們在代碼片段中使用_dog__標(biāo)記所做的那樣。

5.受保護(hù)的屬性

在上一節(jié)中,我們討論了私有屬性,但是受保護(hù)的屬性呢?Python中與受保護(hù)屬性對應(yīng)的屬性名稱只有一個下劃線。不像雙下劃線會導(dǎo)致混亂,單下劃線前綴不會改變Python解釋器處理這些屬性的方式&mdash;&mdash;它只是Python編程世界的一個慣例,表示他們(例如,編碼器)不希望你訪問這些屬性。但是,如果你堅持要訪問它們,你仍然可以這樣做。讓我們看看下面的代碼。

>>> class Dog: ...     def __init__(self, breed, name): ...         self.breed = breed...         self.name = name...         self.__tag = f"{name} | {breed}" ...         self._nickname = name[0]

我們通過創(chuàng)建一個名為_nickname的實例屬性來更新類Dog。正如其名稱使用下劃線前綴所表明的那樣,按照約定,它被認(rèn)為是一個“受保護(hù)”的屬性。我們?nèi)匀豢梢詫⑦@些受保護(hù)的屬性作為其他“公共”屬性來訪問,但是一些ide或Python編輯器不會為這些非公共屬性提供提示(例如,自動完成提示)。有關(guān)這些使用Jupyter筆記本的例子,請參見屏幕截圖。

Python中的高階概念屬性知識點有哪些

如果我們使用模塊而不是類,就像我們在這里所做的那樣,當(dāng)我們使用from _module import  *導(dǎo)入模塊時,帶有下劃線前綴的名稱將不會被導(dǎo)入,從而提供了一種機(jī)制來限制對這些“受保護(hù)的”屬性的訪問。

到此,相信大家對“Python中的高階概念屬性知識點有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI