類與對象
類:
是一組相關屬性和行為的集合。可以看成是一類事物的模板,使用事物的屬性特征和行為特征來描述該 類事物。
舉例:貓。
屬性:名字、體重、年齡、顏色。 行為:走、跑、叫。
對象:
類的具體體現,實現。
舉例:一只小貓。
屬性:tom、5kg、2 years、yellow。 行為:溜牆根走、蹦躂的跑、喵喵叫。
類與對象的關系
- 類是對一類事物的描述,是抽象的。
- 對象是一類事物的實例,是具體的。
- 類是對象的模板,對象是類的實體。
- 對象是根據類來創建的,類中有什么對象就有什么
舉例:當我們提到手機的時候,我們就能想到手機它能夠,打電話、聽電話、看視頻、看圖片、聽音樂、發信息等基礎功能。
但是,我們並不能知道這個手機是什么顏色、品牌、價格等具體實物,這就是類
使用紅色的5000元的華為手機,打着電話,那這個手機就是一個對象。
Python中一切皆對象。
1.類的創建
- 創建語法
-
#類的創建 ''' 注意:類名的首字母需要大寫,類名也可使用多個單詞組成,但是,每個單詞的首字母都要大寫 請遵循這個規范 ''' class Student: #使用class關鍵字創建了Student這個類 pass #Python中一切皆對象,那么這個Student是對象嗎?內存有開辟空間嗎? print(id(Student)) #查看是否開辟空間及其內存地址 1872433931728 print(type(Student)) #查看Student的數據類型 <class 'type'> print(Student) #查看Student的值 <class '__main__.Student'>
-
- 類的組成
- 類屬性:類中方法外的變量稱為類屬性,被該類的所有對象共享
- 實例屬性:定義在類的方法中的屬性
- 實例方法
- 靜態方法:使用類名直接訪問
- 類方法:使用類名直接訪問
-
class Student: native_pace = "中國" #在類里面定義的變量,稱為類屬性 #初始化方法__init__(self): 當創建對象時,系統會自動調用該方法,從而實現對對象進行初始化 注意:__new__才是構造方法(為對象開辟空間) def __init__(self,name,age): self.name = name #實例屬性 self.age = age #實例屬性 #實例方法 在類之外定義的叫做函數,在類里面定義的叫做方法 def eat(self): #實例方法必須傳遞一個形參self,可其他名字 print("學生在吃飯") # 使用staticmethod關鍵字定義靜態方法 @staticmethod def fun(): #靜態方法不傳遞任何參數 print("使用了staticmethod進行修飾,所以我是靜態方法") #使用classmethod關鍵字定義類方法 @classmethod def cm(cls): #類方法必須傳遞一個形參cls(即class),可其他名字 print("使用了classmethod進行修飾,所以我是類方法")
-
2.對象的創建
- 創建類和對象
class Student: native_pace = "中國" #在類里面定義的變量,稱為類屬性 #初始化__init__(self): 當創建對象時,系統會自動調用該方法,從而實現對對象進行初始化 def __init__(self,name,age): self.name = name self.age = age #實例方法 在類之外定義的叫做函數,在類里面定義的叫做方法 def eat(self): #實例方法必須傳遞一個形參self,可其他名字 print("學生在吃飯") # 使用staticmethod關鍵字定義靜態方法 @staticmethod def fun(): #靜態方法不傳遞任何參數 print("使用了staticmethod進行修飾,所以我是靜態方法") #使用classmethod關鍵字定義類方法 @classmethod def cm(cls): #類方法必須傳遞一個形參cls,可其他名字 print("使用了classmethod進行修飾,所以我是類方法") student_1 = Student("張三",20) print(id(student_1)) #查看student_1實例對象的空間地址 1229230570848(10進制)--->0x0000011E33D9FD60(16進制) print(type(student_1)) #查看student_1的數據類型 <class '__main__.Student'> print(student_1) #查看student_1實例對象的值 0x0000011E33D9FD60 可以看出實際輸出的是內存地址
- 對象使用類的屬性和方法
-
student_1 = Student("張三",18) print(student_1.age) #18 print(student_1.name) #張三 print(student_1.native_pace) #中國 (這個是類屬性) student_1.fun() #使用了staticmethod進行修飾,所以我是靜態方法 student_1.eat() #張三 學生在吃飯 student_1.cm() #使用了classmethod進行修飾,所以我是類方法 #使用類名調用方法 Student.eat(student_1) #張三 學生在吃飯 #類方法的使用方法 Student.cm() #靜態方法的使用方法 Student.fun()
-
- self參數:
- 類的所有方法都必須至少有一個名為self的參數,並且必須是方法的第一個參數。
- 如果把類比作制造汽車的圖紙,那么由實例化的對象才是正真可以開的汽車。根據一張圖紙可以設計出千千萬萬的汽車,他們長得都差不多,但是它們都有不同的屬性,如顏色不同、內飾不同、所以self就相當於每輛車的編號,有了self,就可以輕輕松松找到對應的車了。
- 在Python中,由同一個類可以生成無數個對象,當一個對象的方法被調用時,對象會將自身的引用作為第一個參數傳遞給該方法,那么Python就知道需要操作哪個對象的方法了。
3.動態綁定屬性和方法
- 雖然簡單粗暴,但是在實際開發中不推薦使用
- 如果在程序運行時,沒有找到屬性,那么程序會報錯
- 這些屬性應該在定義類時就封裝在類的內部,而不是在類的外部進行添加
#為對象stu_1動態綁定屬性gender stu_1.gender = "女" print(stu_1.gender) #print(stu_2.gender) #報錯,因為實例化對象stu_2並沒有屬性gender #為對象stu_1動態綁定函數,注意:show函數要提前定義好,否則在賦值時,會拋出異常 def show(): print("這是一個被",stu_1,"綁定的show函數") stu_1.show = show stu_1.show() #stu_2.show() #此處代碼報錯,因為對象str_2並沒有綁定show函數
4.初始化方法
- 當使用 類名() 創建對象時,會自動執行以下操作:
- 為對象在內存中分配空間 ——創建對象
- 為對象的屬性設置初始值 ——初始化方法( __init__ )
- 這個初始化方法就是__init__方法,是對象的內置方法
- init方法是用來定義一個類具有哪些屬性的方法!
- 在實例化對象時,會自動調用init方法
-
#沒有寫調用函數的代碼,但是init中的代碼在實例化時被調用了。 class Cat: def __init__(self): print("該方法在實例化對象時,會被調用") Tom = Cat() #該方法在實例化對象時,會被調用
- 在初始化方法內部定義屬性
- 在__init__方法內部使用 self.屬性名 = 屬性初始值 就可以 定義屬性
- 定義屬性之后,在實例化對象時,對象都會具備該屬性
-
class Cat: def __init__(self): print("該方法在實例化對象時,會被調用") self.name = "Tom" Tom = Cat() #該方法在實例化對象時,會被調用 print(Tom.name) #Tom
- 改造初始化方法——初始化的同時設置初始值
- 在開發中,如果希望在 創建對象的同時,就設置對象的初始屬性,可以對__init__方法進行改造
- 把需要用的到屬性值,定義成__init__屬性
- 在方法內部使用 self.屬性名 = 形參 接受對象傳遞過來的參數
-
class Cat: def __init__(self,name): self.name = name def eat(self): print(self.name,"在吃東西") Tom = Cat("Tom") bl = Cat("小黑") Tom.eat() #Tom 在吃東西 bl.eat() #小黑 在吃東西
- 對象的生命周期
- 應用場景:
- __init__改造初始化方法,讓創建對象更加靈活
- __del__對象在銷毀前會自動被調用的一個方法,如果希望對象在銷毀前,可以再做一些事情,可以考慮以下__del__方法
- 生命周期
- 一個對象從調用 類名() 創建,聲明周期開始
- 一個對象__del__方法一旦被調用,聲明周期結束
-
class Cat: def __init__(self,name): self.name = name def eat(self): print(self.name,"在吃東西") def __del__(self): print("我無了") Tom = Cat("Tom") Tom.eat() #Tom 在吃東西 print("*"*25) #運行結果 Tom 在吃東西 ************************* 我無了
如果使用del在分割線前摧毀對象,看下執行效果
Tom = Cat("Tom") Tom.eat() del Tom print("*"*25) #運行結果 Tom 在吃東西 我無了 *************************
由此可以看出當對象銷毀時,對自動調用__del__方法
- 應用場景:
5.詳解
5.1術語 --實例
- 使用面向對象開發,第1步是設計類
- 使用類名()創建對象,創建對象的步驟有兩步:
- 在內存中為對象開辟空間
- 調用初始化方法 __init__ 為對象初始化
- 對象創建后,內存中就有一個實實在在 的存在 ——實例
-
注意:
-
每一個對象 都有自己獨立的內存空間,保存各自
-
多個對象的方法在內存中只有一份,在調用方法時,需要把對象引用 傳遞到方法內部
實例化對象時,實例屬性會被分配好空間,但是方法不會,方法會在對象調用方法時(即實例方法時),將對象的地址傳遞給類的這個方法,
告訴類的這個方法是該對象在調用在調用這個方法(因此對象的實例方法是保存在類所在的內存空間)
5.2類是以個特殊的對象
- Python中一切皆對象:
- class AAA 定義的類,屬於類對象
- obj1 = AAA() 屬於 實例對象
- 在程序運行時,類同樣會被加載到內存
- 在Python中,類是一個特殊的對象——類對象
- 在程序運行時,類對象在內存中只有一份,使用一個類可以創建出很多個對象實例
- 除了封裝實例的屬性和方法外,類對象也可以擁有自己的屬性和方法:
- 類屬性
- 類方法
- 通過 類名. 的方式可以訪問類的屬性或者調用類的方法
5.3類屬性和實例屬性
- 概念和使用
- 類屬性 就是給類 定義的屬性
- 通常用來記錄 與這個類相關的特征
- 類屬性不會用來記錄具體對象的特征
- 示例需求
- 定義一個工具類
- 每個工具都由自己的name
- 需求——知道 使用這個工具類創建了多少個工具對象
1 #類屬性演示 2 class Tool(object): 3 #使用賦值語句定義類屬性count,用來記錄創建工具對象的總數 4 count = 0 5 def __init__(self,name): 6 self.name = name 7 #針對類屬性做一個計數+1 8 Tool.count += 1 9 10 #創建工具對象 11 tool_1 = Tool("斧子") 12 tool_2 = Tool("榔頭") 13 tool_3 = Tool("鐵錘") 14 print(tool_3.count) #3 15 print(Tool.count) #3 16 17 #動態綁定屬性賦值 18 tool_3.count = 6 19 ''' 20 調用對象的屬性和方法時,搜索屬性和方法的方式為 21 先搜索對象的屬性和方法,如果沒有找到然后 22 再搜索類的屬性和方法。 23 ''' 24 print(tool_3.count) 25 """ 26 運行結果:6 27 如果動態綁定屬性並賦值,那么只是在對象的內存空間存在該屬性及其值, 28 搜索時會先搜索對象的內存空間,在去搜索類的內存空間, 29 tool_3進行了動態綁定屬性 count = 6 , 30 那么對象 tool_3 的空間就有該屬性和值 31 """ 32 print(Tool.count) #3
- 屬性的獲取機制
- Python中的屬性存在一個向上查找的機制
- 因此要訪問屬性的兩種方式:
- 類名.類屬性
- 對象.類屬性 (不推薦)
- 如果使用 對象.屬性 = 值 賦值語句,只會給對象添加一個屬性,而不會影響到類屬性的值
- 代碼演示:查看5.3“統計實例化對象個數”
5.4類方法
- 類屬性 就是針對 類對象 定義的值
- 使用賦值語句在class關鍵字下方可以定義類屬性
- 類屬性用於記錄與這個類相關的特征
- 類方法就時針對類對象定義的方法
- 在類方法內部可以直接訪問類屬性或者直接調用其他的類方法
- 語法格式:
-
@classmethod def 類方法名(cls): pass
-
- 類方法需要用 修飾器 @classmethod 來標識,告訴解釋器這是一個類方法
- 類方法的 第一個參數 應該是 cls
- 由哪一個類調用的類方法,方法內的cls就是哪一個類的引用
- 這個參數和實例方法的第一個參數 self 類似
- 提示:使用其他名稱也可以,不過習慣使用cls
- 在方法內部:
- 可以通過cls.訪問類屬性
- 也可以通過cls.調用其他類方法
- 代碼演示
-
1 #類方法 2 class Tool(object): 3 count = 0 4 def __init__(self,name): 5 self.name = name 6 Tool.count += 1 7 8 @classmethod 9 def show_tool(cls): 10 print("對象工具的總數:",cls.count) 11 12 t_1 = Tool("剪刀") 13 t_2 = Tool("榔頭") 14 Tool.show_tool() #對象工具的總數: 2 15 t_1.show_tool() #對象工具的總數: 2
5.5靜態方法
- 在開發時,如果需要在類中封裝一個方法,這個方法
- 既 不需要 訪問 實例屬性 或者調用 實例方法
- 也 不需要 訪問 類屬性 或這調用 類方法
- 這個時候,可以把這個方法封裝成一個靜態方法
- 語法:
-
@staticmethod def 靜態方法名(): pass
-
- 靜態方法需要用 修飾器 @staticmethod 來標識,告訴解釋器這是一個靜態方法
- 通過 類名. 調用 靜態方法
-
class Dog(object): count = 0 @staticmethod def run(): print("一只狗在跑") Dog.run()
案例:

1 #類和對象的練習 2 class Game(object): 3 top_score = 0 4 def __init__(self,player_name): 5 self.player_name = player_name 6 7 @staticmethod 8 def show_help(): 9 print("幫助信息:讓僵屍打開大門") 10 11 @classmethod 12 def show_top_score(cls): 13 print("歷史記錄:%d" % cls.top_score) 14 15 def start_game(self): 16 print("%s開始游戲啦······" % self.player_name) 17 18 #顯示幫助信息 19 Game.show_help() 20 #顯示歷史記錄 21 Game.show_top_score() 22 #創建游戲着 23 xm = Game("小明") 24 #小明開始游戲 25 xm.start_game()