前言
前面我們總結過了python的關鍵字、運算符、內置函數、語法糖等與python魔法方法之間的關系,現在我們更細一點,看看python的面向對象編程有哪些常用的魔法屬性和魔法方法。
魔法屬性
對於一個類,python定義了許多可用的魔法屬性,有些每個類都默認存在,有些需要用戶手動定義。
__dict__
__dict__屬性可以說是一個類最常用的屬性之一了,它又分為類的__dict__屬性和實例的__dict__屬性。
class Person(object):
eye = 2
hand = 2
def __init__(self, name):
self.name = name
def run(self):
print('run')
@classmethod
def eat(cls):
print('eat')
if __name__ == "__main__":
person = Person('cai')
print(Person.__dict__)
print(person.__dict__)
-
類的__dict__屬性存儲了類定義的所有類屬性、類方法等組成的鍵值對,但不包括繼承而來的屬性和方法
-
實例的__dict__屬性存儲了所有的實例屬性的鍵值對,如果沒有就為空;__init__方法其實就是對__dict__屬性的初始化賦值;
__doc__
該屬性記錄了類的說明文檔,用類和實例引用指向的都是類的__doc__屬性,如果沒有默認為None。
class Person(object):
"""person"""
pass
per = Person()
print(per.__doc__) # person
__module__
該屬性記錄類定義的位置,如果定義的位置正好是主程序,那么該值為"_main_",否則是類屬於的模塊的名字;
class Person(object):
"""person"""
pass
per = Person()
print(per.__module__) # __main__
__class__
該屬性指向該實例的類,即實例指向類對象,類對象指向元類;
class Person(object):
"""person"""
pass
per = Person()
print(per.__class__) # <class '__main__.Person'>
print(per.__class__()) # 創建了一個新的實例
print(Person.__class__) # <class 'type'>
# 在一個類的內部直接使用__class__指代類本身。
__slots__
該屬性起到限制動態綁定屬性和方法的作用,該屬性是一個元組,默認是不存在的,需要手動定義並且只對當前的類起作用,只有添加到元組中的名字才能被動態添加屬性,否則報錯!
class Person(object):
__slots__ = ('name','age','run')
def __init__(self):
self.height = 100 # 報錯
def run(self):
print('run')
if __name__ == "__main__":
from types import MethodType
person = Person()
person.name = 'cai'
person.run = MethodType(run,person)
person.run()
-
__slots__屬性定義好后,限制了一個類的實例的屬性以及可以動態添加的屬性和方法;
-
__slots__屬性定義好后,不得在類中定義元組中已有的同名的方法;
魔法方法
__new__
該方法是類創建實例調用的第一個方法,返回一個實例;這是一個實例從無到有必須調用的方法,在單例模式中常用,其他不常用。
class Person(object):
def __new__(cls, *args, **kwargs):
print(args)
return object.__new__(cls)
if __name__ == "__main__":
person = Person('cai')
創建實例時會將參數傳入new方法,但new方法中無法更改參數。
__init__
該方法可以說是類最常用的方法了,python在調用new方法后會緊接着調用init方法,我們將實例的一些初始化操作放在該方法中,即對__dict__屬性進行操作;
class Person(object):
def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
print(key,value)
super().__setattr__(key,value)
if __name__ == "__main__":
person = Person('cai')
print(person.__dict__) # {'name': 'cai'}
-
所有的“self.name = name”這種語法糖,python會先調用setattr魔法方法,該魔法方法對__dict__屬性中添加鍵值對;
-
self一定是__new__方法的返回值,如果返回的是1,那么self就是1.
__del__
該方法在實例對象引用計數變為0或del關鍵字調用的時候觸發執行。
__repr__
該方法在print()調用或repr()調用時執行,用來定義對類的信息的描述,每個類都應該定義這個方法。
總結
-
類的常用魔法屬性有__dict__,__doc__,__mould__,__slots__,其中slots屬性需要自定義,其他屬性默認存在;
-
構造類常用init,new,del方法,它們在類創造、初始化、銷毀時觸發;