Python的oop概述
python是面向對象的語言,那么究竟什么是面向對象?
首先理解類
類:在中文中的定義,許多相同或相似事物的綜合。根據這個定義,類是許多相同或相似的實物聚在一起的。譬如,人類,鳥類,花類等。
面向對象的三個特征
類的單個具體實例可以稱之為對象,把類具體化單個實體的過程,這個過程稱為類的實例化!
面向對象程序設計中的術語對象基本上可以看做數據(特性)以及由一系列可以存取,操作這些數據的方法所組成的集合。
面向對象的三個基本特征:封裝,繼承,多態。
創建對象的過程稱之為實例化,當一個對象被創建之后,包含三個方面的特性:對象的句柄,屬性和方法。對象的句柄用于區分不同的對象,當對象被創建后,該對象會獲取一塊存儲空間,存儲空間的地址即為對象的標識。
- 多態:對不同的類的對象使用同樣的操作。
- 封裝:對外部世界隱藏對象的工作細節。
- 繼承:以普通的類為基礎類建立專門的類對象。
通過實例理解面向對象的一些術語和三個基本特征:
構造方法與析構函數
- 構造方法:在實例化時做的一些初始化工作。
- 析構函數:在實例銷毀時,執行的一些操作。
實例化上面的類,
>>> a = People("China","hitler",20) #實例化一個類時,這時候構造函數會自動執行>>> a.get_info() #通過實例訪問類中的實例方法 -------------------The hitler info-------------------- The hitler comes from China, is 20 old在類中定義屬性時,若屬性是以雙下劃線開始的則為私有屬性,例如self.__age屬性,而像self.country和self.name屬性則是公有屬性,無論是私有屬性還是公有屬性,每個通過實例化得到的類都有這些屬性。
在實例化時,我們可以像給函數傳入參數那樣,給類傳入參數,而這些參數的最終被賦值的操作就是在構造函數中執行的。構造函數在類實例化的時候會自動執行。
注意私有屬性和實例屬性的訪問方法的不同:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> a.name #訪問實例屬性 'hitler' >>> a.country #訪問實例屬性 'China' >>> a.__age #方位私有屬性 Traceback (most recent call last):File "<input>", line 1, in <module> AttributeError: 'People' object has no attribute '__age' >>> a._People__age #私有屬性的訪問方法,實例化名._類名__私有屬性名 20 >>> del a #刪除一個實例,這時候,析構函數會自動執行 hitler has died #析構函數:在實例銷毀的時候自動執行的,通常用于做一些收尾的工作,關閉一些數據庫連接或者關閉打開的臨時文件。析構函數:在實例銷毀的時候自動執行的,通常用于做一些收尾的工作,關閉一些數據庫連接或者關閉打開的臨時文件。
在上面的例子中,使用del刪除了實例a,然后會自動返回析構函數執行的結果。
可以對實例進行增加,刪除,修改操作:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' 對象屬性的增刪改 >>> A = People("USA", "jobs", "53") >>> A.country #可以通過實例修改對應的屬性值 'USA' >>> A.country = "UKA" >>> A._People__age = 55 >>> A.get_info() ##可以看到實例的屬性值已經修改 -------------------The jobs info-------------------- The jobs comes from UKA, is 55 old #可以通過del刪除某個屬性 >>> del A.country >>> A.get_info() #報錯,沒有對應的country屬性 Traceback (most recent call last):File "<input>", line 1, in <module>File "E:\pycharm\class_method.py", line 14, in get_infoprint("The %s comes from %s, is %d old" % (self.name, self.country, self.__age)) AttributeError: 'People' object has no attribute 'country' -------------------The jobs info-------------------->>> A.country = "China" #添加屬性 >>> A.get_info() #可以看到屬性添加成功 -------------------The jobs info-------------------- The jobs comes from China, is 55 old注意上面的通過實例對屬性的增加,刪除,修改操作僅對當前的實例有效;而對于類的其余實例則沒有效果。可以做如下測試以證明:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> a = People("USA","swift",29) #實例化一個對象 >>> a.pos = "singer" #給對象添加一個pos屬性 >>> a.pos #對象a具有pos屬性 'singer'>>> B = People("UKA","king",80) #再實例化一個對象B>>> B.pos Traceback (most recent call last): #對象B沒有pos屬性File "<input>", line 1, in <module> AttributeError: 'People' object has no attribute 'pos'>>> a.get_info() -------------------The swift info-------------------- The swift comes from USA, is 29 old >>> b.get_info() -------------------The king info-------------------- The king comes from UKA, is 80 old解釋:
創建類的時候python會在內存中為類開辟一段內存空間,實例化的時候,python會為每一個實例開辟一段內存空間,每個實例的內存空間都是相互獨立的,因此更改了a的內存空間,并不會影響B的內存空間。
若想使更改的效果,對類的每一個實例都生效,可以使用類變量。
在類變量之前,先說一下self參數。在類中定義的方法,每個方法都有一個self參數,那么self參數該如何理解?
- 在上面的實例中,通過類實例化了兩個對象a和b,那么這兩個對象都有get_info()方法,但是在調用的時候并沒有出錯,我們只能通過某一個具體對象得到這個對象的信息,也就是說我們只能通過a的get_info()方法得到對象a的相關信息,而不是得到b的信息。這個的實現就是因為self參數的作用。
- 在實例化的過程時,python會執行構造函數,做一些初始化的工作,這時候python會為這個實例開辟一段內存空間,會把這個實例名(通過self參數傳遞)和一些屬性信息一起存入內存,這樣調用的時候,通過self參數來區分不同的實例可以準確的調用到對應的屬性信息。
類變量:
首先滿足上面提到的,讓更改對每一個實例都生效。
class People(object):addr = "Earth" # 類變量def __init__(self, country, name, age=23):self.country = countryself.name = nameself.__age = age然后對上面的類進行實例化操作,如下:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> a = People("USA","swift", 29) #實例化兩個類 >>> b = People("China","wxz", 24) >>> a.addr #這兩個類都有一個addr屬性,注意addr類變量在類中定義的方法 'Earth' >>> b.addr 'Earth'>>> a.addr = "Moon" #注意這樣做只是在實例a中添加了實例屬性addr,而不是修改類變量addr。 >>> a.addr #實例a訪問的是實例屬性中的addr。 'Moon' >>> b.addr #而實例b訪問的是類變量addr。因此結果不同 'Earth' >>> People.addr = "Moon" #修改類變量,這時候實例a仍然訪問的是實例屬性addr,而實例b訪問的是類變量addr。 >>> a.addr 'Moon' >>> b.addr 'Moon' #再實例化一個實例對象c,可以發現c的addr屬性已經是修改之后的屬性。 >>> c = People("UKA", "King",88) >>> c.addr #實例對象c訪問的是類變量addr。 'Moon'在上面的實例中,我們給實例a添加一個實例屬性addr,而這時候類變量也有一個屬性addr,那么在訪問的時候實例會怎么去調用對應的值呢?
通過以上的例子可以得出如下結論:屬性查找,首先查找實例本身是否有對應的屬性,若找到則返回結果,停止查找;否則就繼續查找類中的屬性變量。
在這里實例a因為添加了add實例r屬性,因此實例a只會返回實例本身的addr結果;而實例b和實例c,因為本身的沒有addr實例屬性(構造函數中沒有定義),因此會返回類變量addr的值。
類變量是類的各個實例共有的屬性。當然這個屬性也可以放在構造函數中,在每個實例初始化的時候,就會自動生成這個屬性。
但是上面提到過python會為每個實例開辟一個內存空間,因此當實例非常巨大的時候,這樣做會占用存儲空間。采用類變量的形式更節省空間。
封裝:
在這個實例中有一個簡單的方法就是get_info()。對于一個對象也就是實例來說,要想得到這個對象的具體信息,只需要調用get_info()這個方法即可,然后就會返回對象的具體信息。但是具體是怎么樣得到這些信息的,這個實例是不知道的。這種形式就是封裝。把一些功能實現的細節不對外暴露,隱藏起來就是封裝。
經典類與新式類:
- python2中默認創建的都是經典類,但創建類時使用object參數時,就是新式類。
- python3中創建的類都是新式類,但習慣上使用object參數。
- 經典類與新式類的區別在多種繼承中可以用到
繼承:
- 繼承就是一個類繼承了另一個類,繼承的新類擁有父類屬性和方法,實現代碼的重復使用和代碼的擴展。
- 再繼承時,可以對父類的一些屬性和方法進行重寫。
- 需要特別注意的是構造方法的重寫。
上面定義了一個父類People,兩個子類teacher和student,都繼承了people。
實例化操作:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' a = People("wxz") b = Teacher(name="steve", pos="teacher", school="Peking university") d = Student(name="job", pos="Stuent", score=88, course=("數學","語文","物理"))In [6]: a.get_info() My name is wxz, I have not a workIn [7]: b.get_info() My name is steve, I am a teacher The colleage is Peking universityIn [8]: d.get_info() My name is job, I am a Stuent My score is 88 I have learned the 數學 語文 物理實例化的每一個對象都可以調用get_info()方法,得到其對應的信息。這三個對象是不一樣的,分別為people, teacher,student對象。
若有一個函數,只要傳入對應的對象,然后就可以調用函數得到對應的信息。如下這種形式:
在這個例子中,并不知道a,b,d是什么樣的對象,要做的只是把這三個對象傳入了print_intfo函數,然后函數會自動返回對應的對象信息。
這里只有一個print_info的接口,但是不同的對象都可以調用這個接口,這種行為就叫做多態。
多態就是一種接口的多種使用。
下面一個簡單的多態實例
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' list1 Out[22]: ['a', 'f', 'd', 's', 'f', 'a', 's', 'd', 'f'] #列表tuple1 Out[23]: ('f', 'g', 'a', 'g', 'f', 'd', 'g', 'd', 'f') #元組len(list1) Out[24]: 9len(tuple1) Out[25]: 9對于len()函數來說并不知道list1是列表,tuple1是元組,len()函數只是接受一個參數對象,然后返回這個參數對象的長度。也可以理解為多態的一種使用。
面向對象的三個基本特征:封裝,繼承,多態。
面向的對象的屬性:
-
靜態屬性
-
私有屬性
-
? 實例屬性
-
? 類屬性(類變量)
-
-
動態屬性(就是方法)
- 實例方法
- ? 私有方法–和私有屬性一樣是雙下劃線開始的,調用形式和私有屬性一樣,只能通過類中的方法調用
總結
以上是生活随笔為你收集整理的Python的oop概述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python uuid 介绍
- 下一篇: Python构造栈结构