關於Python物件導向編程的知識點總結,python物件導向編程
前言
如果你以前沒有接觸過物件導向的程式設計語言,那你可能需要先瞭解一些物件導向語言的一些基本特徵,在頭腦裡頭形成一個基本的物件導向的概念,這樣有助於你更容易的學習Python的物件導向編程。
接下來我們就來瞭解關於Python物件導向編程的知識點吧。
類與執行個體
類是對象的定義,而執行個體是"真正的實物",它存放了類中所定義的對象的具體資訊。
類、屬性和方法命名規範
類名通常由大寫字母打頭。這是標準慣例,可以協助你識別類,特別是在執行個體化過程中(有時看起來像函數調用)。還有,資料屬性(變數或常量)聽起來應當是資料值的名字,方法名應當指出對應對象或值的行為。
另一種表達方式是:資料值應該使用名詞作為名字,方法使用謂詞(動詞加對象)。資料項目是操作的對象、方法應當表明程式員想要在對象進行什麼操作。
在定義的類中,大致遵循這樣的方針,資料值像 “name”, “phone” 和 “email”,行為如 “updatePhone”,“updateEmail”。這就是常說的 “混合記法(mixedCase)” 或 “駱駝記法(camelCase)”。Python 規範推薦使用駱駝記法的底線方式,比如, “update_phone”,“update_email”。類也要細緻命名,像 “AddrBookEntry”, “RepairShop” 等等就是很好的名字。
class AddrBookEntry(object): def __init__(self, name, phone, email): self.name = name self.phone = phone self.email = email def update_phone(self, phone): self.phone = phone def update_email(self. email): self.email = email
新式類與舊式類
新式類和經典類聲明的最大不同在於,所有新式類必須繼承至少一個父類。如果沒有可繼承的類,則可繼承 object 類。object 是“所有類之母” ,它位於所有類繼承結構的最上層。如果沒有直接或間接的子類化一個對象,那麼就定義了一個經典類。即如果沒有指定一個父類,或者如果所子類化的基本類沒有父類,這樣就是建立了一個經典類。
在 Python3 中定義的類,預設就是新式類,而在 Python2 中要定義一個新式類則必須繼承 object 或者繼承一個新式類。
self 變數
類的方法與普通的函數只有一個特別的區別,即它們必須有一個額外的第一個參數名稱,但是在調用這個方法的時候你不必為這個參數賦值,Python 會提供這個值。這個特別的變數指對象本身,按照慣例它的名稱是 self。雖然可以給這個參數任何名稱,但是強烈建議使用 self 這個名稱,其他名稱都是不贊成使用的。
__init__() 方法
__init__() 類似於類構造器,但實際上並不是一個構造器。Python 建立執行個體後,在執行個體化過程中,調用 __init__() 方法,當一個類被執行個體化時,就可以定義額外的行為,比如,設定初始值或者運行一些初步診斷代碼,這主要是在執行個體被建立後,執行個體化調用返回這個執行個體之前,去執行某些特定的任務或設定。
綁定及非Binder 方法
在 Python 中,訪問類的方法可以通過執行個體也可以通過類來直接存取。但是 Python 嚴格要求,沒有執行個體,方法是不能被調用的。這種限制即 Python 所描述的綁定概念(binding),在此,方法必須綁定(到一個執行個體)才能直接被調用。非綁定的方法可能可以被調用,但執行個體對象一定要明確給出,才能確保調用成功。然而,不管是否綁定,方法都是它所在的類的固有屬性,即使它們幾乎總是通過執行個體來調用的。在 Python 中的類方法也是一種對象。可以簡單的理解就是,通過類直接存取的方法稱為“未綁定的方法”,而通過執行個體訪問的方法稱為“綁定的方法”:
1. 未綁定的類方法:沒有 self
通過類來引用方法返回一個未Binder 方法對象。要調用它,你必須顯示地提供一個執行個體作為第一個參數。
2. 綁定的執行個體方法:有 self
通過執行個體存取方法返回一個綁定的方法對象。Python 自動地給方法綁定一個執行個體,所以我們調用它時不用再傳一個執行個體參數。
樣本:
class Test: def func(self, message): print messageobject1 = Test()x = object1.funcx("Binder 方法對象,執行個體是隱藏的")t = Test.funct(object1, "未Binder 方法對象,需要傳遞一個執行個體")# t("未Binder 方法對象,需要傳遞一個執行個體") # 錯誤的調用
類屬性與執行個體屬性
類屬性僅是與類相關的資料值,和執行個體屬性不同,類屬性和執行個體無關。這些值像靜態成員那樣被引用,即使在多次執行個體化中調用類,它們的值都保持不變。不管如何,靜態成員不會因為執行個體而改變它們的值,除非執行個體中顯式改變它們的值。 執行個體屬性與類屬性的比較,類似於自動變數和靜態變數,但這隻是籠統的類推。在你對自動變數和靜態變數還不是很熟的情況下,不要深究這些。
類和執行個體都是名字空間。類是類屬性的名字空間,執行個體則是執行個體屬性的。
可採用類來訪問類屬性,如果執行個體沒有同名的屬性的話,也可以用執行個體來訪問。
私人化
Python並不直接支援私人方式,而要靠程式員自己把握在外部進行特性修改的時機。
為了讓方法或者特性變為私人(從外部無法訪問),只要在它的名字前面加上雙底線即可。由雙底線 __ 開始的屬性在運行時被“混淆”,所以直接存取是不允許的。
實際上,在 Python 帶有雙底線的屬性或方法並非正真意義上的私人,它們仍然可以被訪問。在類的內部定義中,所有以雙底線開始的名字都被“翻譯”成前面加上單底線和類名的形式:
>>> class TestObj(object):... __war = "world"... ... def __init__(self):... self.__har = "hello"... ... def __foo(self):... print(self.__har + self.__war)... ... ... >>> t = TestObj()>>> dir(t)['_TestObj__foo', '_TestObj__har', '_TestObj__war', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']>>> t.__warTraceback (most recent call last): File "<input>", line 1, in <module> t.__warAttributeError: 'TestObj' object has no attribute '__war'>>> t.__harTraceback (most recent call last): File "<input>", line 1, in <module> t.__harAttributeError: 'TestObj' object has no attribute '__har'>>> t.foo()Traceback (most recent call last): File "<input>", line 1, in <module> t.foo()AttributeError: 'TestObj' object has no attribute 'foo'>>> t._TestObj__war'world'>>> t._TestObj__har'hello'>>> t._TestObj__foo()helloworld
__slots__ 類屬性
正常情況下,當我們定義了一個 class,建立了一個 class 的執行個體後,我們可以給該執行個體綁定任何屬性和方法,這就是動態語言的靈活性。在 Python 中預設用字典來儲存執行個體的屬性。
樣本:
>>> class A():... pass... >>> a = A()>>> a.name = "huoty">>> a.age = 25>>> print a.namehuoty>>> print a.age25>>> a.__dict__{'age': 25, 'name': 'huoty'}
字典位於執行個體的“心臟” 。 __dict__屬性跟蹤所有執行個體屬性。舉例來說,你有一個執行個體 inst,它有一個屬性 foo,那使用 inst.foo 來訪問它與使用 inst.__dict__['foo'] 來訪問是一致的。
字典會佔據大量記憶體,如果你有一個屬性數量很少的類,但有很多執行個體,那麼正好是這種情況。為記憶體上的考慮,可以使用 __slots__ 屬性來替代 __dict__ 。
, __slots__ 是新式類的特性。基本上, __slots__ 是一個類變數,由一序列對象組成,由所有合法標識構成的執行個體屬性的集合來表示。它可以是一個列表,元組或可迭代對象。也可以是標識執行個體能擁有的唯一的屬性的簡單字串。任何試圖建立一個其名不在 __slots__ 中的名字的執行個體屬性都將導致 AttributeError 異常:
>>> class SlotedClass(object):... __slots__ = ("foo", "bar")... ... >>> c = SlotedClass()>>> c.foo = 42>>> c.bar = "hello">>> c.goo = "don't think so"Traceback (most recent call last): File "<input>", line 1, in <module>AttributeError: 'SlotedClass' object has no attribute 'goo'
這種特性的主要目的是節約記憶體。其副作用是某種類型的"安全",它能防止使用者隨心所欲的動態增加執行個體屬性。帶 __slots__ 屬性的類定義不會存在 __dict__ 了(除非你在 __slots__ 中增加 __dict__ 元素)。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的協助,如果有疑問大家可以留言交流。