Python的魔術方法(魔法方法)(一)

  • Python中的魔術方法是由官方定義好的,它們會在合適的時機被自動調用。
  • 魔法方法的形式:以兩個下劃線開始並以兩個下劃線結束。舉例:__init__

本篇先介紹__init__,__del__,__str__,__repr__,__call__五個魔術方法
點擊查看下一篇Python的魔術方法(魔法方法)(二)


__init__方法

__init__方法,在創建一個新對象時被自動調用。
如果希望在創建對象的同時,就設置對象的屬性,可以對__init__方法進行修改。

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age


# 在創建時,必須指定屬性name和age的值
person1 = Person('燕小六', 28) 

注意

  • __init__方法裏的參數self參數在創建對象時不需要傳遞參數。Python解釋器會把創建好的對象引用直接賦值給self
  • 對於多個實例而言,實例的屬性單獨保存,有各自獨立的內存地址。
  • 在類的內部,可以使用self來使用屬性好調用方法;在類的外部,需要使用對象名來使用屬性和調用方法。
  • 方法是所有對象共享的,只佔用一份內存空間,方法被調用時會通過self來判斷是哪個對象調用了實例方法。

__del__方法

當刪除對象時,python解釋器會默認調用__del__方法。

class Person():
    def __init__(self, name, age):
        print('__init__方法被調用了')
        self.name = name
        self.age = age

    def __del__(self):
        print('__del__方法被調用了')


s = Person('邢捕頭', 34)
del s
print(1)

運行結果:

__init__方法被調用了
__del__方法被調用了
1

如果刪除最後兩行語句,運行結果爲下:

__init__方法被調用了
__del__方法被調用了

當程序運行結束後,系統會自動回收內存,自動調用__del__方法刪除實例。


__str__方法

__str__方法在兩種情況下會被調用:

  1. 直接對實例使用print()語句
  2. 對實例使用str()

直接對print(實例)情況

一般情況下,直接對實例使用print()語句,輸出結果是<__main__.類名 object at 內存地址>

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age


s = Person('邢捕頭', 34)
print(s)  # <__main__.Person object at 0x0000029A23F1A488>

如果我想讓打印實例的結果是指定內容,需要如何修改?
重寫__str__方法,並將返回指定內容,必須是字符串

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return 'Hello'


s = Person('邢捕頭', 34)
print(s)  # Hello

對實例使用str()情況

對實例對使用str(),再輸出的結果也是<__main__.類名 object at 內存地址>

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age


s = Person('邢捕頭', 34)
a = str(s)
print(a) # <__main__.Person object at 0x00000221C741A488>

假如你需要讓轉成字符串的實例對象的輸出結果是指定內容,也是重寫__str__方法。

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return 'Hi'


s = Person('邢捕頭', 34)
a = str(s)
print(a)  # Hi

當然,有時候我們的需求往往比僅僅輸出Hello或Hi要複雜。
在重寫方法時,我們仍可以調用實例和類的屬性,一般使用__str__來輸出實例的屬性。

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return 'name:{} age:{}'.format(self.name, self.age)


s = Person('邢捕頭', 34)
a = str(s)
print(a)  # name:邢捕頭 age:34

__repr__方法

__repr__方法和__str__方法功能類似,都是用來修改一個對象的默認打印內容。在打印一個對象時,如果沒有重寫__str__方法,它會自動來查找__repr__方法。如果這兩個方法都沒有,會直接打印這個對象的內存地址。

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return 'Hi'


class Student():
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def __repr__(self):
        return 'Hi'

    def __str__(self):
        return 'Hello'


a = Person('邢捕頭', 34)
print(a) # Hi

b = Student('白展堂', 98)
print(b) # Hello

注意
一般來說,__str__方法的結果更加在意可讀性,而__repr__方法的結果更加在意正確性。


__call__方法

當對實例後面直接加括號時,python將自動調用__call__方法。

class Person():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __call__(self, *args, **kwargs):
        print('__call__被調用了')


a = Person('邢捕頭', 34)
a()

運行後將輸出:

__call__被調用了

我們可以利用修改__call__方法使其實現複雜功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章