Python入門系列19 - 面向?qū)ο笃?二)
Python入門系列19

面向?qū)ο笃ǘ?/p>
本篇文字為2621字,閱讀時間約為10分鐘。
1
前言
哈嘍呀Everybody,又到了更新干貨的時間了,繼續(xù)python入門系列的回歸之路,面向?qū)ο笃牡诙拢嫦驅(qū)ο蟮纳婕暗臇|西實在是太多了,所以打算拆開三次寫吧,后面還有一次面向?qū)ο笃谴蛩銓懲赀@篇之后用面向?qū)ο蟮脑O(shè)計思想來一波實戰(zhàn)篇教學,依然是和安全相關(guān)的,敬請期待.....
2
實例對象中的self
回顧下上一章中,學習了定義一個對象(類)的方法,并且這個類中有自己的類變量以及實力變量,還有自己對應的方法以及構(gòu)造方法。在實例方法中有個特殊的關(guān)鍵詞需要默認傳入 -- self。來看下引用上節(jié)的例子。
class?GirlFriend():
????#?交過的女朋友個數(shù)
????total_nums?=?0
????#?初始化構(gòu)造方法
????def?__init__(self,name,age):
????????self.name?=?name
????????self.age?=?age
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
girlFriend?=?GirlFriend('人類女孩',18)???#?實例化
girlFriend.say_feature()
實際上,self這個關(guān)鍵字并不一定非得叫self,如果學過java的同學一定知道this這個關(guān)鍵詞,特指在一個類中實例對象生成后的本身,而python中的self與其一致,我們可以將self修改成this來看下程序會不會正常運行。

可以看到上圖,改成this后依然成功運行,所以self只是python中的一個官方寫法,具體你要定義成什么樣子的默認第一個參數(shù),隨你喜好,但是推薦默認self就好啦。
3
實例對象中的變量機制(__dict__)
通過__dict__? 可以查看實例對象的屬性。什么意思呢?來看下:
class?GirlFriend():
????#?交過的女朋友個數(shù)
????total_nums?=?0
????#?初始化構(gòu)造方法
????def?__init__(self,?name,?age):
????????self.name?=?name
????????self.age?=?age
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
girlFriend?=?GirlFriend('人類女孩',?18)??#?實例化
print(girlFriend.__dict__)

可以看到結(jié)果,將實例化后的對象中的變量成員以字典的形式打印出來,name和age是實例變量,而人類女孩和18便是我通過創(chuàng)建對象時傳入的參數(shù)。
4
實例方法訪問變量
實例方法:見名知意,即類中定義的方法,需要實例化對象后才能調(diào)用的方法稱之為實例方法。比如在上面的GirlFriend類中的say_feature(),就叫實例方法。那么問題來了,實例方法可以直接訪問實例變量,這是大家都可以想到的,比如在say_feature()中通過self.name調(diào)用了實例變量name。那實例方法中如何訪問類的變量呢?在上面的代碼中,類變量就是total_nums,也就是你迄今為止交過女朋友的總數(shù)量。
先來個錯誤的例子:
class?GirlFriend():
????#?交過的女朋友個數(shù)
????total_nums?=?0
????#?初始化構(gòu)造方法
????def?__init__(self,?name,?age):
????????self.name?=?name
????????self.age?=?age
????????print(f'訪問類變量total_nums:{total_nums}')
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
girlFriend?=?GirlFriend('人類女孩',?18)??#?實例化
print(girlFriend.__dict__)

看到控制臺報錯,輸出沒有定義total_nums,說明這種方式在實例方法中直接訪問類變量是錯誤的。
正確的例子1:

實際上在上一節(jié)的python小課堂的末尾處,提到過如何在類外訪問類變量,直接通過類.變量即可訪問,在實例對象內(nèi)部也可以通過這種方式進行訪問。
正確的例子2:

# 通過 self.__class__ 調(diào)用類變量也可以進行調(diào)用
self.__class__.total_nums ?
類變量還有個特性,就是實例化對象將其共有,這種場景也許在以后的編程中會遇到,我這里依然以女朋友舉例,每個實例變量是你每個不同女票的名字和年齡,而假設(shè)你每次交一個女票,這個交女朋友的總數(shù)total_nums就會增加1。
來看下代碼示例:
class?GirlFriend():
????#?交過的女朋友個數(shù)
????total_nums?=?0
????#?初始化構(gòu)造方法
????def?__init__(self,?name,?age):
????????self.name?=?name
????????self.age?=?age
????????self.__class__.total_nums?+=?1
????????print(f'迄今為止交到的女朋友個數(shù)total_nums:{self.__class__.total_nums}')
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
girlFriend?=?GirlFriend('人類女孩1',?18)??#?實例化
girlFriend2?=?GirlFriend('人類女孩2',?23)??#?實例化
girlFriend3?=?GirlFriend('人類女孩3',?20)??#?實例化

看到結(jié)果,每次實例化一個女盆友,總數(shù)都會增加一次
使用場景自行細細品味一番吧......
再多說一句,方法和變量之間的關(guān)系:變量其實就是我們?nèi)粘Kf的數(shù)據(jù),而方法就是如何去處理數(shù)據(jù),也就是將變量讀取后進行相關(guān)處理。這層處理關(guān)系就是方法和變量的關(guān)系!
5
類方法
在本章開篇處介紹了實例方法,那么類方法則是不需要進行實例化對象,可以直接通過類.方法進行調(diào)用。來看下面的例子:
class?GirlFriend():
????#?交過的女朋友個數(shù)
????total_nums?=?0
????#?初始化構(gòu)造方法
????def?__init__(self,?name,?age):
????????self.name?=?name
????????self.age?=?age
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
????#?類方法
????@classmethod
????def?make_girlfriend_count(cls):
????????cls.total_nums?+=?1
????????print(f'迄今為止交到的女朋友個數(shù)total_nums:{cls.total_nums}')
GirlFriend.make_girlfriend_count()
GirlFriend.make_girlfriend_count()
girlFriend?=?GirlFriend('人類女孩1',?18)??#?實例化
girlFriend.make_girlfriend_count()
通過在方法上面加上@classmethod,這樣來定義類方法,這個寫法可以先了解下,后序會講到python的裝飾器,就知道這種寫法的意義了。classmethod,中文翻譯就是類方法的意思,在方法的默認參數(shù)中,需要默認給出一個cls作為參數(shù),這里類似實例方法中的self字段,他們都是形式上的默認參數(shù),名字可以改變,不一定必須叫cls,python默認會給出cls,而cls是class的簡寫,也指代的是自己本身。
將交到女朋友的個數(shù)作為類方法來演示下最終的運行結(jié)果:

調(diào)用類方法時,只需要通過類名稱直接調(diào)用即可。當然python也支持先實例化在調(diào)用類方法,也不會報錯,可以看到上圖中最后一次 調(diào)用,但是絕不推薦這樣用,因為沒有意義!
6
靜態(tài)方法
class?GirlFriend():
????#?交過的女朋友個數(shù)
????total_nums?=?0
????#?初始化構(gòu)造方法
????def?__init__(self,?name,?age):
????????self.name?=?name
????????self.age?=?age
????#?行為,說出自己的特征
????def?say_feature(self):
????????print(f'我的姓名:{self.name}')
????????print(f'我的年齡:{self.age}')
????#?類方法
????@classmethod
????def?make_girlfriend_count(cls):
????????cls.total_nums?+=?1
????????print(f'迄今為止交到的女朋友個數(shù)total_nums:{cls.total_nums}')
????@staticmethod
????def?study_language(language,score):
????????print(f'我在學習{language},熟練分數(shù):{score}')
GirlFriend.study_language('中文',90)

注:在靜態(tài)方法和類方法中,是無法直接用self.xxx引用實例變量的。可自行嘗試!
類方法和靜態(tài)方法的區(qū)別:在調(diào)用時,都可以通過類名直接進行調(diào)用。但是一般不推薦使用靜態(tài)方法,因為類方法同樣可以實現(xiàn),并且可以通過默認參數(shù)cls直接引用類中的類變量使用。
7
總結(jié)
以上就是python面向?qū)ο蟮牡诙糠郑竺嫖視嬕粋€思維導圖來整理下學到的相關(guān)知識,其實圖一畫出來,邏輯就非常清晰了。回顧下本章內(nèi)容,介紹了self的應用,類方法的應用,實例方法的應用以及相互之間訪問的關(guān)系。文章略長,還望耐心觀看....切忌浮躁(也是說給自己的!)
至此完!
