1. 程式人生 > >【python小課堂專欄】python小課堂19 - 面向物件篇(二)

【python小課堂專欄】python小課堂19 - 面向物件篇(二)

python小課堂19 - 面向物件篇(二)

前言

哈嘍呀Everybody,又到了更新干貨的時間了,繼續python小課堂的迴歸之路,面向物件篇的第二章,面向物件的涉及的東西實在是太多了,所以打算拆開三次寫吧,後面還有一次面向物件篇,但是打算寫完這篇之後用面向物件的設計思想來一波實戰篇教學,依然是和安全相關的,敬請期待…

例項物件中的self

回顧下上一章中,學習了定義一個物件(類)的方法,並且這個類中有自己的類變數以及實力變數,還有自己對應的方法以及構造方法。在例項方法中有個特殊的關鍵詞需要預設傳入 – self 。來看下引用上節的例子。

class GirlFriend
(): # 交過的女朋友個數 total_nums = 0 # 初始化構造方法 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這個關鍵字並不一定非得叫self,如果學過java的同學一定知道this這個關鍵詞,特指在一個類中例項物件生成後的本身,而python中的self與其一致,我們可以將self修改成this來看下程式會不會正常執行。

在這裡插入圖片描述

可以看到上圖,改成this後依然成功執行,所以self只是python中的一個官方寫法,具體你要定義成什麼樣子的預設第一個引數,隨你喜好,但是推薦預設self就好啦。

例項物件中的變數機制(dict)

通過**dict** 可以檢視例項物件的屬性。什麼意思呢?來看下:

class GirlFriend():
    # 交過的女朋友個數
total_nums = 0 # 初始化構造方法 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__)

在這裡插入圖片描述

可以看到結果,將例項化後的物件中的變數成員以字典的形式打印出來,name和age是例項變數,而人類女孩和18便是我通過建立物件時傳入的引數。

例項方法訪問變數

例項方法:見名知意,即類中定義的方法,需要例項化物件後才能呼叫的方法稱之為例項方法。比如在上面的GirlFriend類中的say_feature(),就叫例項方法。那麼問題來了,例項方法可以直接訪問例項變數,這是大家都可以想到的,比如在say_feature()中通過self.name呼叫了例項變數name。那例項方法中如何訪問類的變數呢?在上面的程式碼中,類變數就是total_nums,也就是你迄今為止交過女朋友的總數量。
先來個錯誤的例子:

class GirlFriend():
    # 交過的女朋友個數
    total_nums = 0

    # 初始化構造方法
    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:

在這裡插入圖片描述

實際上在上一節的python小課堂的末尾處,提到過如何在類外訪問類變數,直接通過類.變數即可訪問,在例項物件內部也可以通過這種方式進行訪問。

正確的例子2:

在這裡插入圖片描述


# 通過 self.__class__ 呼叫類變數也可以進行呼叫

self.__class__.total_nums   

類變數還有個特性,就是例項化物件將其共有,這種場景也許在以後的程式設計中會遇到,我這裡依然以女朋友舉例,每個例項變數是你每個不同女票的名字和年齡,而假設你每次交一個女票,這個交女朋友的總數total_nums就會增加1。

來看下程式碼示例:

class GirlFriend():
    # 交過的女朋友個數
    total_nums = 0

    # 初始化構造方法
    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.__class__.total_nums += 1
        print(f'迄今為止交到的女朋友個數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)  # 例項化

在這裡插入圖片描述

看到結果,每次例項化一個女盆友,總數都會增加一次使用場景自行細細品味一番吧…

再多說一句,方法和變數之間的關係:變數其實就是我們日常所說的資料,而方法就是如何去處理資料,也就是將變數讀取後進行相關處理。這層處理關係就是方法和變數的關係!

類方法

在本章開篇處介紹了例項方法,那麼類方法則是不需要進行例項化物件,可以直接通過類.方法進行呼叫。來看下面的例子:

class GirlFriend():
    # 交過的女朋友個數
    total_nums = 0

    # 初始化構造方法
    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'迄今為止交到的女朋友個數total_nums:{cls.total_nums}')

GirlFriend.make_girlfriend_count()
GirlFriend.make_girlfriend_count()
girlFriend = GirlFriend('人類女孩1', 18)  # 例項化
girlFriend.make_girlfriend_count()

通過在方法上面加上 @classmethod,這樣來定義類方法,這個寫法可以先了解下,後序會講到python的裝飾器,就知道這種寫法的意義了。classmethod,中文翻譯就是類方法的意思,在方法的預設引數中,需要預設給出一個cls作為引數,這裡類似例項方法中的self欄位,他們都是形式上的預設引數,名字可以改變,不一定必須叫cls,python預設會給出cls,而cls是class的簡寫,也指代的是自己本身。

將交到女朋友的個數作為類方法來演示下最終的執行結果:

在這裡插入圖片描述

呼叫類方法時,只需要通過類名稱直接呼叫即可。當然python也支援先例項化在呼叫類方法,也不會報錯,可以看到上圖中最後一次 呼叫,但是絕不推薦這樣用,因為沒有意義!

靜態方法

靜態方法:定義時,不需要像類方法和例項方法預設傳入引數,在方法上面宣告一個叫@staticmethod的裝飾器,staticmethod,中文翻譯靜態方法。來看下寫法:


class GirlFriend():
    # 交過的女朋友個數
    total_nums = 0

    # 初始化構造方法
    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'迄今為止交到的女朋友個數total_nums:{cls.total_nums}')

    @staticmethod
    def study_language(language,score):
        print(f'我在學習{language},熟練分數:{score}')

GirlFriend.study_language('中文',90)

在這裡插入圖片描述

**注:**在靜態方法和類方法中,是無法直接用self.xxx引用例項變數的。可自行嘗試!

類方法和靜態方法的區別:在呼叫時,都可以通過類名直接進行呼叫。但是一般不推薦使用靜態方法,因為類方法同樣可以實現,並且可以通過預設引數cls直接引用類中的類變數使用。

總結

以上就是python面向物件的第二部分,後面我會畫一個思維導圖來整理下學到的相關知識,其實圖一畫出來,邏輯就非常清晰了。回顧下本章內容,介紹了self的應用,類方法的應用,例項方法的應用以及相互之間訪問的關係。文章略長,還望耐心觀看…切忌浮躁(也是說給自己的!)

至此完!


有想學python的同學,歡迎關注公號:

在這裡插入圖片描述