先劃一下重點:python
魔法方法的命名規則:方法名(先後各有2個下劃線)。函數
一般狀況下,不會主動去調用魔法方法,而是在知足必定的條件下,會自動去調用魔法方法。3d
經常使用的魔法方法有6個,分別是:new、del、str、repr、bytes、call,下面我爲你們一一講解。code
class Person: # __new__不用@classmethod修飾的一個類方法 # 在建立對象的時候,會首先調用該方法 # 若是在該方法中,返回當前類的對象(也即建立對象),接下來會調用__init__方法,對對象進行初始化。不然,__init__方法不會獲得執行 def __new__(cls): return super().__new__(cls) # 這行代碼是建立對象,只是我如今不太明白 Person() # 在咱們寫類的時候,不須要寫這個。這裏講述一下,只是想讓咱們知道。在建立對象的時候,__new__方法比__init__方法,先調用
若一個類中既有new方法,也有init方法,當咱們建立對象時候,首先執行new方法。orm
假如,new方法中沒有return super().new(cls) ,則不會執行init方法。寫上之後,表示再次建立一個對象纔會執行init方法。對象
# 第一段代碼 class Person: def __new__(cls): print("__new__執行") return super().__new__(cls) # 這行代碼是建立對象,只是我如今不太明白 def __init__(self): print("__init__執行") p = Person() # 第二段代碼 class Person: def __new__(cls): print("__new__執行") # return super().__new__(cls) # 假如不返回,當前類的對象,__init__就不會執行 def __init__(self): print("__init__執行") p = Person() # 由於,這裏建立的對象,先去執行new方法了
結果以下:blog
在銷燬對象的時候(對象指的是咱們本身建立的對象),會首先調用該方法。字符串
class Person: def __init__(self): print("__init__執行") # 在該方法中,能夠執行一些清理工做 def __del__(self): print("該對象已經被銷燬") p = Person() # 能夠看出,由於沒有對象銷燬,因此不會調用該方法
結果以下:get
class Person: def __init__(self): print("__init__執行") def __del__(self): print("該對象已經被銷燬") p = Person() del p
結果以下:input
class Person: def __new__(cls): print("__new__執行") return super().__new__(cls) def __init__(self): print("__init__執行") def __del__(self): print("該對象已經被銷燬") # 在使用內建函數(str,format,print)的時候,會自動調用該方法 # 該方法須要返回一個str類型的對象 # def __str__(self): # return "Person類型的對象" p = Person() print(p)
結果以下:
class Person: def __new__(cls): print("__new__執行") return super().__new__(cls) def __init__(self): print("__init__執行") # 在使用內建函數(str,format,print)的時候,會自動調用該方法 # 該方法須要返回一個str類型的對象 def __str__(self): return "Person類型的對象" p = Person() p
結果以下:
class Person: def __new__(cls): print("__new__執行") return super().__new__(cls) def __init__(self): print("__init__執行") # 在使用內建函數(str,format,print)的時候,會自動調用該方法 # 該方法須要返回一個str類型的對象 def __str__(self): return "Person類型的對象" p = Person() print(p)
結果以下:
class Person: def __new__(cls): print("__new__執行") return super().__new__(cls) def __init__(self): print("__init__執行") def __del__(self): print("該對象已經被銷燬") def __str__(self): return "Person類型的對象" # __str__ 與 __repr__ 的區別:兩者都是返回對象的字符串表示。 # 不一樣的是:__str__ 返回的一般是讓人容易閱讀的格式。__repr__返回的是面向Python解釋器的,一般格式:<內容> def __repr__(self): return "<Person class>" p = Person() print(str("abc")) # 結果是abc,這個更加接近人閱讀模式 print(repr("abc")) # 結果是'abc',字符串原本就是帶引號的,因此這個和python解釋器更相近
結果以下:
該方法在使用內建函數(bytes)的時候,會自動調用.
class Person: def __new__(cls): print("__new__執行") return super().__new__(cls) def __init__(self): print("__init__執行") def __del__(self): print("該對象已經被銷燬") def __str__(self): return "Person類型的對象" def __repr__(self): return "<Person class>" def __bytes__(self): return b"byte person class" p = Person() print(bytes(p))
結果以下:
把對象當成函數來使用的時候,會自動調用。
class Person: def __new__(cls): print("__new__執行") return super().__new__(cls) def __init__(self): print("__init__執行") def __del__(self): print("該對象已經被銷燬") def __str__(self): return "Person類型的對象" def __repr__(self): return "<Person class>" def __bytes__(self): return b"byte person class" # 把對象當成函數來使用的時候,會自動調用該方法 def __call__(self): print("把對象當成函數來使用的時候") p = Person() p()
結果以下:
這4個函數分別是:hasattr、getattr、delattr、setattr,下面咱們一一來說述。
class Person(): pass p = Person() print(hasattr(p,"name")) p.name = "3417" print(hasattr(p,"name"))
結果以下:
class Person(): pass p = Person() print(getattr(p, "name"))
結果以下:
class Person(): pass p = Person() p.name = "關注一波?" print(getattr(p, "name"))
結果以下:
class Person(): pass p = Person() print(getattr(p,"age","沒有屬性返回的默認值"))
結果以下:
class Person(): pass p = Person() setattr(p,"age",20) print(p.age)
結果以下:
class Person(): pass p = Person() setattr(p,"age",20) delattr(p,"age") print(hasattr(p,"age"))
結果以下:
注意1 :動態操做屬性沒有直接操做屬性簡便,可是比直接訪問屬性靈活。
注意2 :直接訪問屬性必須在寫代碼時,就須要知道屬性的名字,而動態操做屬性沒有此限制(這在其餘語言中叫作'"反射")。
class Person(): pass p = Person() unknown = input("請輸入屬性名:") value = input("請輸入屬性值:") setattr(p, unknown, value) print(getattr(p, unknown))
結果以下: