Python面向物件之面向物件基本概念
過程和函式:過程類似於函式,只能執行,但是沒有返回結果;函式不僅能執行,還能返回結果。
面向過程和麵向物件 基本概念
面向過程-怎麼做
- 把完成某一個需求的所有步驟從頭到尾逐步實現;
- 根據開發需求,將某些功能獨立的程式碼封裝成一個又一個函式;
- 最後完成的程式碼,就是順序的呼叫不同的函式。
特點
- 注重步驟和過程,不注重職責分工;
- 如果複雜需求,程式碼會變得很複雜;
- 開發複雜專案,沒有固定的套路,開發難度很大。
面向物件-誰來做
相比較函式,面向物件是更大的封裝,根據職責在一個物件中封裝多個方法。
- 在完成某一個需求前,首先確定職責-要做的事情(方法)
- 根據職責確定不同的物件,在物件內部封裝不同的多個方法
- 最後完成的程式碼,就是順序的讓不同的物件呼叫不同的方法。
特點
- 注重物件和職責,不同的物件承擔不同的職責;
- 更加適合應對複雜的需求變化,是專門應對複雜專案開發,提供的固定套路;
- 需要在面向過程基礎上,再學習一些面向物件的語法。
- 將資料與函式繫結到一起,進行封裝,這樣能夠更快速的開發程式,減少了重複程式碼的重寫過程
面向物件是基於面向過程的
用面向物件的思維解決問題的重點
當遇到一個需求的時候不用自己去實現,如果自己一步步實現那就是面向過程;應該找一個專門做這個事的人來做。
面向物件(object-oriented ;簡稱: OO) 至今還沒有統一的概念 我們可以把它定義為: 按人們 認識客觀世界的系統思維方式,採用基於物件(實體) 的概念建立模型,模擬客觀世界分析、設 計、實現軟體的辦法。
面向物件程式設計(Object Oriented Programming-OOP) 是一種解決軟體複用的設計和程式設計方法。 這種方法把軟體系統中相近相似的操作邏輯和操作 應用資料、狀態,以類的型式描述出來,以物件例項的形式在軟體系統中複用,以達到提高軟體開發效率的作用。
Python學習交流群:556370268,這裡是python學習者聚集地,有大牛答疑,有資源共享!小編也準備了一份python學習資料,有想學習python程式設計的,或是轉行,或是大學生,還有工作中想提升自己能力的,正在學習的小夥伴歡迎加入學習。
類和物件
類和物件的概念
類
類是對一群具有相同特徵或者行為的事物的一個統稱,是抽象的,不能直接使用;
特徵被稱為屬性;
行為被稱為方法。
物件
物件是由類創建出來的一個具體存在,可以直接使用;
由哪一個類創建出來的物件,該物件就具有在那一個類中定義的屬性和方法;
類和物件的關係
類就是建立物件的模板,應該先有類,在有物件;
一個類可以建立多個物件,不同物件之間屬性可能各不相同;
類中定義了什麼方法,物件中就有什麼屬性和方法,不可能少,但可能多,因為物件可以自己在類外增加屬性
類的設計
在使用面向物件開發前,應該首先分析需求,確定一下,程式中需要包含哪些類。
在程式開發中,要設計一個類,通常要滿足以下三個要素
- 類名 這類事物的名字,滿足大駝峰命名法;
- 屬性 這類事物具有什麼樣的特徵;
- 方法 這類事物具有什麼樣的行為
屬性和方法的確定
對 物件的特徵描述,通常可以定義為屬性
物件具有的行為,通常可以定義為方法
面向物件基礎語法
dir內建函式
在Python中物件幾乎是無所不在的,我們之前學習的變數,資料,函式都是物件;
在Python中可以使用以下兩個方法驗證:
- 在識別符號/資料後輸入一個. ,然後按下tab鍵,ipython會提示該物件能夠呼叫的方法列表;
- 使用內建函式dir傳入識別符號/資料,可以檢視物件內的所有屬性和方法;
部分內建方法說明

image
在互動式下:
def demo(): """這是一個測試函式""" print("hello python") dir(demo) ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] demo.__doc__ '這是一個測試函式'
定義簡單的類
面向物件是更大的封裝,在一個類中封裝多個方法,這樣通過這個類創建出來的物件,就可以直接呼叫這些方法了。
定義只包含方法的類
在python中藥定義一個只包含方法的類,語法格式如下:
class 類名: def 方法1(self, 列表引數): pass def 方法2(self, 列表引數): pass
方法的定義格式和之前學習的函式幾乎一樣;
區別在於第一個引數必須是self;
注意,類名的命名規則要符合大駝峰命名法;
建立物件
當一個類定義完成後,要使用這個類來建立物件,語法格式如下:
物件變數 = 類名()
第一個面向物件程式
class Cat: """定義一個貓類""" def eat(self): print("小貓愛吃魚") def drink(self): print("小貓要喝水") tom = Cat() tom.eat() tom.drink()
引用概念的強調
- 在面向物件開發中,引用的概念是同樣使用的。
- 在python中使用類建立物件之後,tom變數仍然記錄的是物件在記憶體中的地址,也就是tom變數引用了新建的貓物件;
- 使用print函式輸出物件變數,可以輸出這個變數引用的物件是由哪一個類建立的物件,以及在記憶體中的地址(十六進位制)
Python學習交流群:556370268,這裡是python學習者聚集地,有大牛答疑,有資源共享!小編也準備了一份python學習資料,有想學習python程式設計的,或是轉行,或是大學生,還有工作中想提升自己能力的,正在學習的小夥伴歡迎加入學習。
驗證引用示例
class Cat: """定義一個貓類""" def eat(self): print("小貓愛吃魚") def drink(self): print("小貓要喝水") tom = Cat() tom.eat() tom.drink() print(tom) # <__main__.Cat object at 0x0000019D74C30C18> addr = id(tom) print("%d" % addr) # 以十進位制表示地址 1775780432920 print("%x" % addr) # 以十六進位制表示地址 19d74c30c18
一個類建立多個物件 示例
class Cat: """定義一個貓類""" def eat(self): print("小貓愛吃魚") def drink(self): print("小貓要喝水") tom = Cat() bosi = Cat() bosi2 = bosi print(tom) # <__main__.Cat object at 0x000001A4A0B1FB70> print(bosi) # <__main__.Cat object at 0x000001A4A0B1FC50> print(bosi2) # <__main__.Cat object at 0x000001A4A0B1FC50>
方法中的self函式
在類外給物件附加屬性
- 不修改類,在類外給物件增加屬性;但不建議這樣使用,因為物件屬性的封裝應該封裝在類的內部。
- 類外增加屬性方法:在類的外部的程式碼中直接通過 物件變數. 設定一個屬性即可;
類外給物件附加屬性示例
class Cat: """定義一個貓類""" def eat(self): print("小貓愛吃魚") def drink(self): print("小貓要喝水") tom = Cat() tom.name = "湯姆" bosi = Cat() bosi.name = "波斯"
利用self 在 類封裝的方法中 輸出物件屬性
由哪一個物件呼叫的方法,方法內的self就是哪一個物件的引用;
在類封裝的方法內部,self就表示當前呼叫方法的物件自己;
呼叫方法時,不需要傳遞self引數;
在類的外部,通過變數名. 訪問物件的屬性和方法;
在類封裝的方法內部中,通過self. 訪問物件的屬性和方法。
class Cat: """定義一個貓類""" # 哪一個物件呼叫的方法,方法內的self就是哪一個物件的引用 def eat(self): print("%s愛吃魚" % self.name) def drink(self): print("%s要喝水" % self.name) tom = Cat() tom.name = "湯姆" tom.eat() tom.drink() bosi = Cat() bosi.name = "波斯" bosi.eat() bosi.drink() # 湯姆愛吃魚 # 湯姆要喝水 # 波斯愛吃魚 # 波斯要喝水
在類外給物件增加屬性的問題
如果是在呼叫方法之後,才設定的屬性,並且呼叫的方法要用到屬性,那麼就會報錯。
class Cat: """定義一個貓類""" # 哪一個物件呼叫的方法,方法內的self就是哪一個物件的引用 def eat(self): print("%s愛吃魚" % self.name) def drink(self): print("%s要喝水" % self.name) tom = Cat() tom.eat() # 報錯 tom.drink() # 報錯 tom.name = "湯姆"
因此,在日常開發中,不推薦在類的外部給物件增加屬性;
物件應該包含有哪些屬性,應該封裝在類的內部。
初始化方法
當使用 類名()建立物件時,會自動執行以下操作:
- 為物件在記憶體中分配空間--建立物件;
- 為物件的屬性 設定初始值--初始化方法(init);
這個初始化方法就是 init 方法, init 是物件的內建方法;
init方法是專門用來定義一個類具有哪些屬性的方法;
在我們用類建立一個物件時,如果類中有初始化方法,會自動呼叫初始化方法。
例如以下程式碼,當我們建立物件時,就算不呼叫方法,也會輸出 “初始化方法”。
class Cat: def __init__(self): print("初始化方法") tom = Cat() # 初始化方法
在初始化方法中定義屬性
在 init 方法內部使用 self.屬性名 = 屬性的初始值 就可以定義屬性;
定義屬性後,再使用Cat類建立的物件,都會擁有該屬性;
class Cat: def __init__(self): print("初始化方法") # self.屬性名 = 屬性的初始值 self.name = "湯姆" def eat(self): print("%s愛吃魚" % self.name) tom = Cat() print(tom.name)
使用引數設定屬性初始值
在開發中,如果希望建立物件的同時,就設定物件的屬性,可以對 init 方法進行改進。
- 把希望設定的屬性,定義成 init 方法的引數
- 在方法內部使用self.屬性名 = 形參 接收外部傳遞的引數
- 在建立物件時,使用類名(屬性1,屬性2,...)呼叫
引數設定屬性初始值示例
class Cat: def __init__(self, new_name): # self.屬性名 = 形參 self.name = new_name def eat(self): print("%s愛吃魚" % self.name) tom = Cat("湯姆") tom.eat() bosi = Cat("波斯") bosi.eat() # 湯姆愛吃魚 # 波斯愛吃魚
內建方法和屬性
del方法
del 方法 會在 執行完所有程式碼後系統自動銷燬物件變數;
因為tom是全域性物件,所以正常執行時 會在所有程式碼結束後自動呼叫 del 方法;
如果使用了del關鍵字刪除tom的全域性變數,則會在執行del tom前 就會自動呼叫 del 方法銷燬物件記憶體;
應用場景
init改造初始化方法,可以讓建立物件更加靈活;
del如果希望在物件被銷燬前,再做一些事情,可以考慮使用 del 方法;
生命週期
一個物件從呼叫 類名()建立物件,生命週期開始;
一個物件的 del 方法一旦被呼叫,生命週期結束;
在物件的生命週期之內,可以訪問物件屬性,或者讓物件呼叫方法。
class Cat: def __init__(self, new_name): # self.屬性名 = 屬性的初始值 self.name = new_name print("%s init" % self.name) def __del__(self): print("%s del" % self.name) def eat(self): print("%s愛吃魚" % self.name) tom = Cat("湯姆") tom.eat() print("-"*50) # 湯姆 init # 湯姆愛吃魚 # -------------------------------------------------- # 湯姆 del
沒執行完所有程式碼就刪除tom物件
class Cat: def __init__(self, new_name): # self.屬性名 = 屬性的初始值 self.name = new_name print("%s init" % self.name) def __del__(self): print("%s del" % self.name) def eat(self): print("%s愛吃魚" % self.name) # tom 是一個全域性變數 tom = Cat("湯姆") tom.eat() # 因為在執行完所有程式碼之前,全域性變數tom就被刪除了,所以會自動呼叫__del__方法,不會等-*50的執行 del tom print("-"*50) # 湯姆 init # 湯姆愛吃魚 # 湯姆 del # --------------------------------------------------
str方法
print(變數物件) 預設看到父類和變數物件的記憶體地址,但 我們可以通過 str 方法來自定義看到的內容 ;
注意, str 方法必須要返回一個字串。
class Cat: def __init__(self, new_name): # self.屬性名 = 形參 self.name = new_name def __str__(self): return "<object_name>-<%s>" % self.name def eat(self): print("%s愛吃魚" % self.name) # tom 是一個全域性變數 tom = Cat("湯姆") tom.eat() print(tom) # 湯姆愛吃魚 # <object_name>-<湯姆>
身份運算子is
身份運算子介紹
身份運算子用於比較兩個物件的記憶體地址是否一致--是否是對同一個物件的引用;
注意,在python中針對None比較時,建議使用is判斷;
身份運算子表

image
is和==的區別
is用於判斷兩個變數引用物件是否是同一個;
==用於判斷引用變數的值是否相等;
a = [1, 2, 3] b = [1, 2] b.append(3) a is b # False a ==b # True
當在判斷None時,建議使用is判斷;
Python學習交流群:556370268,這裡是python學習者聚集地,有大牛答疑,有資源共享!小編也準備了一份python學習資料,有想學習python程式設計的,或是轉行,或是大學生,還有工作中想提升自己能力的,正在學習的小夥伴歡迎加入學習。

image