Python——面向物件程式設計(未完)
文章目錄
一、OOP
Object Oriended Programming,面向物件程式設計,是三大程式設計正規化之一。
其他兩種分別是結構化程式設計、函數語言程式設計。
1、什麼是面向物件
面向物件,Object Oriended,其實譯為以物件為主導 更恰當,因為物件是OOP中的主角,就好像函數語言程式設計中的函式。
2、什麼是物件
Python 中,一切皆物件
一個Python 物件包含三個部分:id(identity 識別碼)、type(物件型別)、
value(物件的值)。
對於類和類的例項,value又可以進一步分為屬性(attribute)和方法(method)。
3、OO和PO
面向過程(Procedure Oriented) | 面向物件(Object Oriended) | |
---|---|---|
優點 | 效能比面向物件高,因為類呼叫時需要例項化,開銷比較大,比較消耗資源 | 易維護、易複用、易擴充套件,由於面向物件有封裝、繼承、多型性的特性,可以設計出低耦合的系統,使系統 更加靈活、更加易於維護 |
缺點 | 沒有面向物件易維護、易複用、易擴充套件 | 效能比面向過程低 |
適用場景 | 比如微控制器、嵌入式開發、 Linux/Unix等一般採用面向過程開發,效能是最重要的因素。 | 系統複雜性高的專案 |
二、類和例項
1、類和例項
類是藍圖,例項(instance)是按藍圖創建出來(例項化)的物件。
2、類屬性和例項屬性
例項屬性一般在__init__()方法中定義。
3、一個簡單的例子
class People:
__count = 0 # 類屬性
def __init__(self, name, age): # 初始化函式
self.name = name # 例項屬性
self.age = age
def speak(self, words):
print(words)
def walk(self):
pass
if ___name__ == '__main__':
A = People('Ez', '20') # 例項化People,並將變數A指向這個例項
4、類的命名
一般採用大駝峰法。如Student、MyClass。
5、一個例項被建立的過程
會經由兩步:
__new__(cls) # 構造例項,eg:剛剛燒出來的陶人
__init__(self) # 初始化例項,eg:上色
這兩個方法都是頂級父類object
的函式。
如果再在子類中定義,屬於函式重寫,此時屬於例項函式
其中,__new__()
必須有return語句,將新構造出來的的例項返回給__init__()
作為引數。
一個例項建立的例子:
class People:
def __new__(cls, name, age):
print("An instance has been created")
return object.__new__(cls) # 沒有return,則__init__()不會被執行
def __init__(self, name, age):
print("An instance is being initialized")
self.name = name
self.age = age
if __name__ == '__main__':
A = People('Ez', '20')
print(A)
輸出
An instance has been created
An instance is being initialized
<__main__.People object at 0x000001E717824400>
銷燬一個例項物件
__del__
方法稱為“析構方法”,用於實現物件被銷燬時所需的操作。比如:釋放物件
佔用的資源,例如:開啟的檔案資源、網路連線等。
Python 實現自動的垃圾回收(GC,Garbage Collection ),當物件沒有被引用時(即引用計數為0),由垃圾回收器自動呼叫__del__
方法。
我們也可以通過del 語句刪除物件,從而保證呼叫__del__方法。
系統會自動提供__del__方法,一般不需要自定義析構方法。
class Person:
def __del__(self):
print("銷燬物件:{0}".format(self))
p1 = Person()
p2 = Person()
del p2
print(p2)
print("程式結束")
執行結果:
銷燬物件:<__main__.Person object at 0x02175610>
程式結束
銷燬物件:<__main__.Person object at 0x021755D0>
三、類和方法
在類中定義的函式一般稱為方法,有別於類外的的普通函式。
類中有3中常見的方法:
1)例項方法(self)
2)類方法(cls)
3)靜態方法(可以理解為輔助方法,與類和例項無關,所以不用傳參self或cls)。
其實還有一種類方法(見程式碼),我們暫且稱之為第二種類方法。
1、例項方法
例項方法是從屬於例項物件的方法。
定義格式:
def 方法名(self [, 形參列表]):
pass
呼叫格式
例項物件.例項方法([實參列表])
要點:
- 定義例項方法時,第一個引數必須為self。和前面一樣,self 指當前的例項物件。
- 呼叫例項方法時,不需要也不能給self 傳參。self 由直譯器自動傳參。
例項物件呼叫例項方法的本質:
A.speak("Hola")
# 直譯器內部解釋為:
People.speak(A, "Hola")
2、類方法
類方法是從屬於“類物件”的方法。
類方法通過裝飾器@classmethod 來定義,格式如下:
@classmethod
def 類方法名(cls [,形參列表]) :
pass
要點如下:
- 必須加裝飾器 @classmethod
- 第一個cls 必須有;cls 指的就是“類物件”本身;
- 呼叫類方法格式:“類名.類方法名(引數列表)”。引數列表中,不需要也不能給cls 傳
值。 - 類方法中訪問例項屬性和例項方法會導致錯誤
- 子類繼承父類方法時,傳入cls 是子類物件,而非父類物件
3、靜態方法
Python 中允許定義與“類物件”無關的方法,稱為“靜態方法”。
“靜態方法”和在模組中定義普通函式沒有區別,只不過“靜態方法”放到了“類的名字空
間裡面”,需要通過“類呼叫”。
靜態方法通過裝飾器@staticmethod 來定義,格式如下:
@staticmethod
def 靜態方法名([形參列表]) :
pass
要點如下:
- @staticmethod 必須位於方法上面一行
- 呼叫靜態方法格式:“類名.靜態方法名(引數列表)”。
- 靜態方法中訪問例項屬性和例項方法會導致錯誤
4、程式碼測試
class People:
__count = 0
def __init__(self, name, age):
self.name = name
self.age = age
People.__count += 1 # 注意,這裡不能使用self.__count,雖然不會報錯
# 例項方法
def speak(self, words):
print(words)
# 類方法,操作類相關的屬性
@classmethod
def getCount(cls):
print(cls.__count)
# 靜態方法
@staticmethod
def test():
print("I am a static method")
# 第二種類方法
def special():
print("I am a special class method")
例項物件呼叫示例:
實際上,A.special()
時, 在直譯器內部是等同於People.special(A)
,所以報異常:TypeError: special() takes 0 positional arguments but 1 was given
類物件呼叫示例:
四、訪問限制
OOP三大特性
封裝 (encapsulation)
隱藏物件的屬性和實現細節,僅對外公開介面,控制在程式中屬性的讀取和修改的訪問級別。
封裝途徑
封裝就是將抽象得到的資料和行為(或功能)相結合,形成一個有機的整體,也就是將資料與操作資料的原始碼進行有機的結合,形成“類”,其中資料和函式都是類的成員。
封裝的目的是增強安全性和簡化程式設計,使用者不必瞭解具體的實現細節,而只是要通過外部介面,以特定的訪問許可權來使用類的成員。
大神文章傳送
[1] Python中self用法詳解
[2] https://www.cnblogs.com/blackmatrix/p/5606364.html
[3] Python中下劃線—完全解讀