- 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__
方法在兩種情況下會被調用:
- 直接對實例使用
print()
語句 - 對實例使用
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__
方法使其實現複雜功能。