首頁 > 軟體

Python物件導向的內建方法梳理講解

2022-10-14 14:01:47

首先class類裡的內建方法,比如:__call__,__str__這些都是在一定條件下自動執行的。

下面我們來介紹幾個內建方法

1、__str__

先講講他的作用,在print列印物件的時候會自動觸發執行

例子1:

class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age
stu1 = Student('xiaoming',18)
print(stu1)      #執行原理就是,先在Student類裡找__str__方法,沒有就去他的父類別找
print(object.__str__(stu1))   #驗證了Student的父類別裡面有__str__方法

輸出結果是

#<__main__.Student object at 0x0000023A1170C128>
#<__main__.Student object at 0x0000023A1170C128>

例子2:

我們可以在Student類自己定義一個__str__方法來驗證,執行print列印操作,原理#是執行了__str__方法的

class Student:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __str__(self):
        print(self.name)
        return '<name:%s age:%s>' %(self.name,self.age)
stu1 = Student('xiaoming',18)
print(stu1)     #這個stu1就是__str__的返回值

輸入結果是:

xiaoming
<name:xiaoming age:18>

補充一下,物件的查詢屬性的順序:物件自己的名稱空間,物件對應類的名稱空間,該類的基礎類別的名稱空間

2、__del__方法

作用是,會在刪除物件之前自動觸發該方法

我就直接上程式碼吧

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __del__(self):
        print('%s 已經被刪除' % self.name)
stu1 = Student('xiaoming', 18)
stu2 = Student('zhangsan', 18)
print('主')

他的執行結果是


xiaoming 已經被刪除
zhangsan 已經被刪除

講講為什麼是這個輸出結果:這個python直譯器的垃圾回收機制吧,一個程式執行完畢,python會回收該程式在記憶體中產生的資料,當執行到print(‘主’),後面沒有程式碼執行了,就會刪掉stu1,stu2這兩個物件,刪除這兩個物件之前呢,會執行__del__方法,所以會出現上面的結果。

3、__call__

在呼叫該物件時,也就是範例化的時候,會自動執行其類和類的基礎類別中的__call__方法,如果沒有的,那麼該物件是不可呼叫的物件

class Student:   #補充:class Student: 相當於就是 Student = type(類名,該類的基礎類別們,類體程式碼產生的名稱空間)
    pass
Student()

分析一下:首先一切皆物件,Student就是一個物件,Student他是通過元類(type)範例化得來的,所以說呼叫Student(),就是去找type元類中找__call__方法去執行,很明顯type類中有__call__方法,執行上面那段程式碼,不會出錯。

下面舉個例子來驗證下上面的結論

class Student:  # (相當於上面例子的type)
    def __init__(self, name, age):
        self.name = name
        self.age = age
stu1 = Student('xiaoming', 18)  # stu1(相當於上面例子的Student)
try:  # 這裡我們通過捕捉異常來列印出錯原因
    stu1()  # 這裡相當於上面Student()
except Exception as e:
    print(e)
    # 列印結果是:'Student' object is not callable
    # 「Student」物件不可呼叫,也就是stu1是不可呼叫的

結論:通過這兩個例子可以得到,只要該物件的類中有__call__方法,那該物件就可以呼叫,也就是範例化。

該物件範例化,就是執行其類中的__call__方法

驗證下:該物件範例化,就是執行其類中的__call__方法

class Teacher:
    def __init__(self, name):
        self.name = name
    def __call__(self, *args, **kwargs):
        print('我被%s呼叫了' % self.name)
tea1 = Teacher('xiaoming')
tea1()

#輸出結果是:我被xiaoming呼叫了

如何通過元類來控制類的呼叫

通過在自定義元類裡的__call__方法,來實現對類的呼叫控制

1、首先類的呼叫原理就是執行元類裡的__call__方法

2、通過__call__方法來實現對物件的初始化操作

class Mymeta(type):
    def __call__(self, *args, **kwargs):  # self就是Student *args和**kwargs就是Student後面的引數
        # print(self)
        # print(args)
        # print(kwargs)
        obj = self.__new__(self)  # 就是建立一個Student的空物件
        self.__init__(obj, *args, **kwargs)  # 執行__init__方法    這裡需要注意查詢順序
        return obj  # 將範例化完的物件返回回去
class Student(object, metaclass=Mymeta):
    def __init__(self, name, age):
        self.name = name
        self.age = age
stu1 = Student('xiaoming', age=18)
print(type(stu1),stu1.__dict__)

這就是類的範例化的整個過程,不過這是我們通過自定義元類來控制類的呼叫,也就是再__call__多些程式碼而已

在預設元類type裡,肯定有__call__方法,該方法下面就是產生個空物件,再執行__init__方法

先講到這三個方法,其他那些__dict__,class,__name__這些就不說了

到此這篇關於Python物件導向的內建方法梳理講解的文章就介紹到這了,更多相關Python物件導向內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com