Python基礎語法(七:類與物件)
不在壓力與疲憊中沉浮,
不在良辰與美景中迷失。
不在奮鬥與競爭中麻木,
不在輝煌與騰飛中失足。
文章目錄
一、Python中的類與物件
1.類與物件的概念
類 和 物件 是 物件導向程式設計的 兩個 核心概念
物以類聚,人以群分
人類
鳥類
植物類
超人類
.....
劃分類的標準是?擁有共同的特性?動作?
類 英文單詞: class
他們有相似點。共同之處
- 類 是對一群具有 相同特徵 或者 行為 的事物的一個統稱,是抽象的,不能直接使用
- 特徵 被稱為 屬性
- 它是什麼樣的
- 特徵 被稱為 屬性
什麼是屬性???
表示的是類/物件的特徵。
特徵是別人不具備的。
類屬性(類變數):
這個類的特徵,這個群體的特徵, 別的類(別的群體)可能不具備
例項屬性(例項變數) :
這個個體的特徵,類當中的其他成員可能不具備。
類屬性的獲取:
類名.屬性
類屬性:可以先天定義也可以 後天學習(手工新增)
class Man:
# 定義類屬性
gender = '男'
power = "強"
handsome = 'very very'
print(Man.power) # Man類的power屬性
print(Man.gender) # Man類的gender屬性
# 後天學習(手工新增的)
Man.hello = 'hello world'
print(Man.hello)
# 例項屬性的後天學習獲取
yuz = Man()
# yuz.handsome = 'very very'
print(yuz.handsome)
kaishi = Man()
kaishi.handsome = '一丟丟'
print(kaishi.handsome)
# 類屬性和例項屬性:
# 類屬性:所有的成員都是一樣的。
# 例項屬性:不是每個成員都一樣
# 第二個區別:
#類屬性,可以被例項、物件訪問
# 例項屬性, 不可以被類獲取
print(Man.eye)
class Man:
# 定義類屬性
gender = '男'
power = "強"
handsome = 'very very'
yuz = Man()
kaishi = Man()
print(yuz.gender)
print(kaishi.gender)
yuz.eye = '藍色'
# AttributeError, 屬性錯誤。
# print(kaishi.eye)
print(Man.eye)
**行為** 被稱為 **方法**
- 它可以做什麼
方法:表示類 、 物件的行為。
方法本質上是函式。
屬性名稱:名詞。
方法:動詞,
方法 vS 函式:
1, self
2, 放在類裡面,縮排的。
3, 呼叫過程不一樣。 方法需要加字首,類名或者物件名。
函式前面要麼不加,要麼加的模組名。
# 物件.方法()
Man().drink()
# 例項方法,物件方法:
1, 第一個引數名稱,規定是 self,
2, 例項方法在呼叫的時候,字首是物件,不能是類
# 類方法:
1, 在方法的上面新增 @classmethod
2, 把例項方法當中的 self 改成 cls,
# 靜態方法
靜態方法表示: 方法的上面加上一個 @staticmethod
不需要用 self, cls 作為固定引數
是剛剛好放在一個類當中的普通函式而已。
除了放在類當中,和普通函式沒什麼區別。
沒有實際作用,和類或者物件沒有關係(聯絡),
為什麼要用靜態方法、為什麼要把普通的函式放到類當中去??
方便管理
呼叫靜態方法。
靜態方法,(普通函式) 只需要在呼叫靜態方法,前面加上類名或者物件名
類外面的普通函式:普通函式不需要加類,模組
實際使用當中:
例項方法: 98% , 例項方法佔大多數情況。
不知道用什麼方法,就用例項方法。
類方法:後面會有特殊情況
靜態方法: 可以用普通函式代替,不是必須的。(管理方便。)
"""
class Man:
# 定義類屬性
gender = '男'
power = "強"
handsome = 'very very'
@staticmethod
def tianqiyubao():
print("天氣預報:今天是晴天。")
@classmethod
def eat(cls):
print("正在吃飯")
return "hello world"
def drink(self):
"""喝。。。"""
pass
def play_game(self):
"""玩遊戲"""
pass
# # 物件.方法()
# Man().drink()
#
# yuz = Man()
# yuz.drink()
# 行為是屬於某一個人的。不能被類呼叫的
# 不 OK, Man.drink()
# 列印函式的呼叫列印出來的是函式的返回值。
# def run():
# pass
#
# print(run())
# print(Man.eat())
# print(Man().eat())
# 靜態方法的使用
Man.tianqiyubao()
Man().tianqiyubao()
- 類 就相當於建造房子時的施工圖紙(blueprint),是一個模板,是負責建立**房子(物件)**的
物件 object: 東西
什麼是物件 object
又被稱為 例項 instance
- 物件 是 由類建立出來的一個具體存在,可以直接使用
- 由 哪一個類 建立出來的 物件,就擁有在 哪一個類 中定義的:
- 屬性
- 方法
- 物件 就相當於用 施工圖紙 建造 的房子
在程式開發中,應該 先有類,再有物件
2. 類與物件的關係
- 類是模板,物件 是根據 類 這個模板建立出來的
- 先有類,再有物件
- 類 只有一個,而 物件 可以有很多個
- 不同的物件 之間 屬性 可能會各不相同
- 類 中定義了什麼 屬性和方法,物件 中就有什麼屬性和方法,不可能多,也不可能少
3.類的設計
在使用面相物件開發前,應該首先分析需求,確定一下,程式中需要包含哪些類!
類的設計要素
在程式開發中,要設計一個類,通常需要滿足一下三個要素:
- 類名
- 滿足大駝峰命名法
- 屬性
- 這類事物具有什麼樣的特徵
- 方法
- 這類事物具有什麼樣的行為
大駝峰命名法
-
每一個單詞的首字母大寫
-
單詞與單詞之間沒有下劃線
確定類名
名詞提煉法 分析 整個業務流程,出現的 名詞,通常就是找到的類
確定屬性和方法
- 對 物件的特徵描述,通常可以定義成 屬性
- 物件具有的行為(動詞),通常可以定義成方法
類的定義:
class 類名:
類的組成部分
類的呼叫:
print(類名)
變數 = 類名
<class '__main__.Man'>
<__main__.Man object at 0x0000022ABEE74670>
看到有尖括號的,一般來說就是一個類 / 物件。
4. 定義類
- 在
Python
中要定義一個只包含方法的類,語法格式如下:
class 類名:
def 方法1(self, 引數列表):
pass
def 方法2(self, 引數列表):
pass
- 方法 的定義格式和之前學習過的函式 幾乎一樣
- 區別在於第一個引數必須是
self
建立物件
- 當一個類定義完成之後,要使用這個類來建立物件,語法格式如下:
物件變數 = 類名()
self
使用 self
在方法內部輸出每個人的名字
由 哪一個物件 呼叫的方法,方法內的
self
就是 哪一個物件的便利貼
-
在類封裝的方法內部,
self
就表示 當前呼叫方法的物件自身 -
呼叫方法時,程式設計師不需要傳遞
self
引數 -
在方法內部
- 可以通過
self.
訪問物件的屬性 - 也可以通過
self.
呼叫其他的物件方法
- 可以通過
- 在
Python
中要定義帶屬性的類,語法格式如下:
初始化方法
-
當使用
類名()
建立物件時,會 自動 執行以下操作:-
為物件在記憶體中 分配空間 —— 建立物件
-
為物件的屬性 設定初始值 —— 初始化方法(
init
)
-
-
這個 初始化方法 就是
__init__
方法,__init__
是物件的內建方法
__init__
方法是 專門 用來定義一個類 具有哪些屬性的方法
在初始化方法內部定義屬性
- 在
__init__
方法內部使用self.屬性名 = 屬性的初始值
就可以 定義屬性 - 定義屬性之後,再使用
Person
類建立的物件,都會擁有該屬性
"""
什麼是初始化??
要通過定義的類得到一個具體的物件。 生出來,造出來。
物件個體,初始化過程保證生出來是不一樣的。
我們自己給東西進行出廠設定。
特定的方法中去控制:
__init__
例項屬性的定義2:
1, 類外面: 物件名.屬性
2, 類裡面: self.屬性
__init__ 定義的形式引數 和 物件的例項化 a = Man() 的實際引數,是一一對應的。
1. 必須 return None
2. 傳入的引數必須要設定成例項屬性,才能被被物件訪問到。
self: 在 **類裡面** ,表示一個 **物件** 他自己。自我, this
cls, : 在 **類裡面** ,表示一個 **類** 他自己。自我, this
例項方法當中,可不可以去定義例項屬性。??
"""
# def run():
# pass
class Man:
# 定義類屬性
gender = '男'
power = "強"
handsome = 'very very'
def __init__(self, name, face_shape='圓臉'):
"""物件的初始化過程。 讓物件之間長得不太一樣。"""
# 定義, 在類裡面,定義例項屬性使用 self.屬性 = ...
self.face = face_shape
self.name = name
@staticmethod
def tianqiyubao():
print("天氣預報:今天是晴天。")
@classmethod
def eat(cls):
print("正在吃飯")
print(cls.power)
return "hello world"
def drink(self, brand):
"""喝。。。"""
print("{} 正在喝 {} 酒".format(self.name, brand))
# self.play_game()
self.eat()
# 定義例項屬性
self.single = False
def play_game(self):
"""玩遊戲"""
print("玩遊戲")
yuz = Man('yuz', '方臉')
# print(yuz.face)
# print(yuz.name)
# yuz.drink('茅臺')
# 整容的權利,可以後天改變屬性
# yuz.face = "帥臉"
# print(yuz.face)
# 初始化以後 。 single 屬性是後天定義的,
yuz.drink('五糧液')
print(yuz.single)
yuz.single = True
print(yuz.single)
# print(a)
5. __str__
方法
- 在
Python
中,使用print
輸出 物件變數,預設情況下,會輸出這個變數 引用的物件 是 由哪一個類建立的物件,以及 在記憶體中的地址(十六進位制表示) - 如果在開發中,希望使用
print
輸出 物件變數 時,能夠列印 自定義的內容,就可以利用__str__
這個內建方法了
注意:
__str__
方法必須返回一個字串
二、身份運算子
身份運算子用於 比較 兩個物件的 記憶體地址 是否一致 —— 是否是對同一個物件的引用
- 在
Python
中針對None
比較時,建議使用is
判斷
運算子 | 描述 | 例項 |
---|---|---|
is | is 是判斷兩個識別符號是不是引用同一個物件 | x is y,類似 id(x) == id(y) |
is not | is not 是判斷兩個識別符號是不是引用不同物件 | x is not y,類似 id(a) != id(b) |
is 與 == 區別
is
用於判斷 兩個變數 引用物件是否為同一個
==
用於判斷 引用變數的值 是否相等
三、 類屬性和例項屬性
1.概念
- 類屬性 就是給 類 定義的 屬性
- 通常用來記錄 與這個類相關 的特徵
- 類屬性 不會記錄具體物件的特徵
動態屬性設定
class Phone:
def __init__(self, number):
self.number = number
phone = Phone('137')
# # 物件.屬性
# print(phone.number)
#
# # 動態獲取屬性
# print(getattr(phone, 'number'))
# 動態獲取不存在的屬性
# print(phone.brand)
# 可以加上 default 引數,設定預設值。當沒有該屬性的屬性,不會報錯。
# 而是返回預設值。
# print(getattr(phone, 'brand', default='蘋果'))
# 動態屬性,屬性名 == 變數
prop_name = 'brand'
# phone.prop_name
# phone.brand
print(getattr(phone, prop_name, '蘋果'))
print(phone.brand)
# 設定 set 屬性。
# print(phone.number)
# setattr(phone, 'number', '155')
# # phone.number = 155
# phone.color = '白色'
# print(phone.number)
四、類方法和靜態方法
1.類方法
- 類屬性 就是針對 類 定義的屬性
- 使用 賦值語句 在
class
關鍵字下方可以定義 類屬性 - 類屬性 用於記錄 與這個類相關 的特徵
- 使用 賦值語句 在
- 類方法 就是針對 類 定義的方法
- 在 類方法 內部可以直接訪問 類屬性 或者呼叫其他的 類方法
語法如下
@classmethod
def 類方法名(cls):
pass
-
類方法需要用 修飾器
@classmethod
來標識,告訴直譯器這是一個類方法 -
類方法的 第一個引數 應該是
cls
- 由 哪一個類 呼叫的方法,方法內的
cls
就是 哪一個類的引用 - 這個引數和 例項方法 的第一個引數是
self
類似 - 提示 使用其他名稱也可以,不過習慣使用
cls
- 由 哪一個類 呼叫的方法,方法內的
-
通過 類名. 呼叫 類方法,呼叫方法時,不需要傳遞
cls
引數 -
在方法內部
-
可以通過
cls.
訪問類的屬性 -
也可以通過
cls.
呼叫其他的類方法
在類方法內部,可以直接使用
cls
訪問 類屬性 或者 呼叫類方法
2.靜態方法
- 在開發時,如果需要在 類 中封裝一個方法,這個方法:
- 既 不需要 訪問 例項屬性 或者呼叫 例項方法
- 也 不需要 訪問 類屬性 或者呼叫 類方法
- 這個時候,可以把這個方法封裝成一個 靜態方法
語法如下
@staticmethod
def 靜態方法名():
pass
- 靜態方法 需要用 修飾器
@staticmethod
來標識,告訴直譯器這是一個靜態方法 - 通過 類名. 呼叫 靜態方法
4.總結
-
例項方法 —— 方法內部需要訪問 例項屬性
-
例項方法 內部可以使用 類名. 訪問類屬性
-
類方法 —— 方法內部 只 需要訪問 類屬性
-
靜態方法 —— 方法內部,不需要訪問 例項屬性 和 類屬性
提問
如果方法內部 即需要訪問 例項屬性,又需要訪問 類屬性,應該定義成什麼方法?
答案
- 應該定義 例項方法
- 因為,類只有一個,在 例項方法 內部可以使用 類名. 訪問類屬性
五、繼承
1.概念
- 子類 擁有 父類 的所有 方法 和 屬性
- 可以單繼承和多繼承
2.語法
class 類名(父類名):
pass
- 子類 繼承自 父類,可以直接 享受 父類中已經封裝好的方法,不需要再次開發
- 子類 中應該根據 職責,封裝 子類特有的 屬性和方法
3.專業術語
Dog
類是Animal
類的子類,Animal
類是Dog
類的父類,Dog
類從Animal
類繼承Dog
類是Animal
類的派生類,Animal
類是Dog
類的基類,Dog
類從Animal
類派生
4.繼承的傳遞性
C
類從B
類繼承,B
類又從A
類繼承- 那麼
C
類就具有B
類和A
類的所有屬性和方法
子類 擁有 父類 以及 父類的父類 中封裝的所有 屬性 和 方法
提問: 哮天犬 能夠呼叫 Cat
類中定義的 catch
方法嗎?
5.方法的重寫
- 子類 擁有 父類 的所有 方法 和 屬性
- 子類 繼承自 父類,可以直接 享受 父類中已經封裝好的方法,不需要再次開發
應用場景
- 當 父類 的方法實現不能滿足子類需求時,可以對方法進行 重寫(override)
重寫 父類方法有兩種情況:
-
覆蓋 父類的方法
-
對父類方法進行 擴充套件
6.覆蓋父類的方法
- 如果在開發中,父類的方法實現 和 子類的方法實現,完全不同
- 就可以使用 覆蓋 的方式,在子類中 重新編寫 父類的方法實現
具體的實現方式,就相當於在 子類中 定義了一個 和父類同名的方法並且實現
重寫之後,在執行時,只會呼叫 子類中重寫的方法,而不再會呼叫 父類封裝的方法
7.對父類方法進行 擴充套件
-
如果在開發中,子類的方法實現 中 包含 父類的方法實現
- 父類原本封裝的方法實現 是 子類方法的一部分
-
就可以使用 擴充套件 的方式
-
在子類中 重寫 父類的方法
-
在需要的位置使用
super().父類方法
來呼叫父類方法的執行 -
程式碼其他的位置針對子類的需求,編寫 子類特有的程式碼實現
-
"""繼承。
父類 子類
繼承如何表示:
class 子類名(父類名):
pass
子類可以實現自己獨有的方法。
子類可以覆蓋父類的方法。 ==》 重寫
super() 超繼承: 使用父類當中的方法。
"""
class Phone:
"""手機"""
def __init__(self, number):
self.number = number
def call(self, to, recorded=False):
"""打電話"""
print(" {} 給 {} 打電話。。".format(self.number, to))
if recorded:
self.record()
def record(self):
"""錄音"""
print("{} 正在錄音".format(self.number))
class SmartPhone(Phone):
"""智慧手機"""
def __init__(self, number, brand):
self.number = number
self.brand = brand
def watch_movie(self, name):
print("正在看電影{}".format(name))
class Iphone(SmartPhone):
# brand = '蘋果'
def __init__(self, number):
super().__init__(number, '蘋果')
# self.number = number
# self.brand = "蘋果"
def face_time(self):
"""錄屏,直播"""
print("{} 正在直播".format(self.number))
def call(self, to, recorded=False, face=False):
"""打電話既可以錄音,也可以facetime"""
# print(" {} 給 {} 打電話。。".format(self.number, to))
#
# if recorded:
# self.record()
super().call(to, recorded=False)
if face:
self.face_time()
# normal_phone = Phone('1')
# print(normal_phone.record())
#
# # 父類當中不能呼叫子類方法。
# # normal_phone.watch_movie("紅海行動")
#
# smart_phone = SmartPhone("2")
# print(smart_phone.record())
# print(smart_phone.number)
# smart_phone.watch_movie('小偷家族')
# 當子類和父類具有同樣的方法或者屬性的時候。
# 父類還是用父類的, 子類不再有父類的,而是用自己的。
# normal = Phone("1")
# smart = SmartPhone(2, '華為')
# 重寫例子2
iphone = Iphone('蘋果5')
iphone.call('開始', face=True)
# smart = SmartPhone("123", '華為')
# smart.call('李三', face=True)
8.關於 super
- 在
Python
中super
是一個 特殊的類 super()
就是使用super
類建立出來的物件- 最常 使用的場景就是在 重寫父類方法時,呼叫 在父類中封裝的方法實現
# super預設會呼叫第一個父類的方法(適用於單繼承 或者只想使用第一個父類的方法) # 02 方式 適用於新式類 # 格式: super(子類類名, self).父類方法名()
總結
類的命名:大駝峰命名: 兩個單詞的首字母大寫。
class PerfectManHelp
函式的命名:下劃線命名:perfect_man_help
變數命名:下劃線命名.
相關文章
- Java基礎系列(七):物件與類(下)Java物件
- Python基礎-類與物件Python物件
- python 基礎語法之物件導向Python物件
- Python3基礎18——類與物件Python物件
- Python爬蟲基礎講解(七):xpath的語法Python爬蟲
- python:類1——類和物件基礎Python物件
- Python基礎:語法基礎(3)Python
- Python 基礎語法Python
- Python基礎語法Python
- php基礎語法_物件導向PHP物件
- 豬行天下之Python基礎——8.1 類與物件Python物件
- python基礎語法—語句Python
- Python的基礎語法Python
- Python基礎(06):if語法Python
- Python基礎語法(二)Python
- Python基礎語法(一)Python
- python 基礎語法(三)Python
- 零基礎入門Python教程4節與基礎語法Python
- Vuejs 基礎與語法VueJS
- Python基礎語法資料Python
- Python3 基礎語法Python
- Java基礎-基礎語法-變數與常量Java變數
- python 基礎習題1--基礎語法Python
- 類的基礎語法閱讀【Python3.8官網文件】Python
- GOLANG簡介與基礎語法Golang
- 零基礎如何快速掌握Python基礎語法?Python
- 快速掌握Python基礎語法(下)Python
- python 基礎語法 - 函式(一)Python函式
- 初學Python(1)基礎語法Python
- 第二課 Python基礎語法Python
- Python基礎語法及應用Python
- Python語法—物件Python物件
- Java基礎-語法基礎Java
- Dart語法篇之物件導向基礎(五)Dart物件
- 『Java 語法基礎』物件導向有哪些特性Java物件
- 【PYTHON】語法基礎 | 開始使用PythonPython
- 基礎語法
- 2.7Python基礎語法(5):註釋與引號Python