面向對象--03魔法方法

python的魔法方法(被雙下劃線包圍)      所謂工廠函數就是類對象
1.構造方法
①__new__(cls[,...])
實例化對象時第一個被調用的方法
cls-->類   如果cls後還有參數,則參數會原封不動的傳給init方法,new方法需要一個實例對象作爲返回值(return),通常爲cls
極少重寫,但當繼承一個不可變類型時需要重寫new方法


__new__方法的調用是發生在__init__之前的。其實當 你實例化一個類的時候,具體的執行邏輯是這樣的:
①.p = Person(name, age)
②.首先執行使用name和age參數來執行Person類的__new__方法,這個__new__方法會 返回Person類的一個實例(通常情況下是使用 super(Persion, cls).__new__(cls, … …) 這樣的方式),
③.然後利用這個實例來調用類的__init__方法,上一步裏面__new__產生的實例也就是 __init__裏面的的 self
所以,__init__ 和 __new__ 最主要的區別在於:
(1)__init__ 通常用於初始化一個新實例,控制這個初始化的過程,比如添加一些屬性, 做一些額外的操作,發生在類實例被創建完以後。它是實例級別的方法。
(2)__new__ 通常用於控制生成一個新實例的過程。它是類級別的方法。

例一
>>> class CapStr(str):
 def __new__(cls,string):
  string = string.upper()
  return str.__new__(cls,string)  #調用基類的new方法
 
>>> a = CapStr('i love someone')
>>> a
'I LOVE SOMEONE'
>>>

例二
假如我們需要一個永遠都是正數的整數類型,通過集成int,我們可能會寫出這樣的代碼。
>>> class PositiveInteger(int):
    def __new__(cls, value):
        return super(PositiveInteger, cls).__new__(cls, abs(value))
>>> i = PositiveInteger(-3)
>>> print(i)
3
>>>

②__init__(self[,...])
 init方法下不能有return返回(或者說返回None)
不能對不可變類型的init方法進行重寫
用於初始化對象的屬性。__init__方法可以在創建對象的時候就設置好屬性。
當創建對象以後,Python解釋器會默認調用__init__(self)方法。
例:使用構造方法
>>> class Car:
 #構造方法
 def __init__(self):
  self.color = '黑色'
  
>>> #創建一個對象,並用變量car保存它的引用
>>> car = Car()
>>> car.color
'黑色'

例:使用帶參構造方法
>>> class Car:
 #帶參構造方法
 def __init__(self,color):
  self.color = color
  
>>> bwm = Car('香檳色')
>>> bwm.color
'香檳色'


2.析構方法
__del__(self)
當所有對象對類的引用都被del之後,纔會調用__del__(self)方法(垃圾回收機制)
用於釋放類所佔用的資源
當刪除一個對象來釋放類所佔用資源的時候,Python解釋器會默認調用__del__(self)方法。

3.有關算術運算的魔法方法
__add__(self,other)    定義加法的行爲+
__sub__(self,other)    定義減法的行爲-
__mul__(self,other)    定義乘法的行爲*
__truediv__(self,other)  定義真除法的行爲/
__floordiv__(self,other)  定義整數除法的行爲//
__mod__(self,other)   定義取模算法的行爲%
__divmod__(self,other)     定義當被divmod()調用時的行爲
__pow__(self,other[,modulo])     定義當被power()調用或**運算時的行爲

4.反運算r
self爲主,other爲輔,當self不支持所用方法時,會調用other的方法
__radd__(self,other)
與上方相同,當左操作數不支持相應的操作時被調用
例一
>>> class int(int):
 def __radd__(self,other):
  return int.__sub__ (self,other)
 
>>> a = int(2)
>>> b = int(6)
>>> a + b
8
>>> 2 + b
4
>>>


例二(1)
>>> class int(int):
 def __rsub__(self,other):
  return int.__sub__ (self,other)
 
>>> a = int(5)
>>> 3 - a
2
>>>
#self傳入的是a

例二(2)
>>> class int(int):
 def __rsub__(self,other):
  return int.__sub__ (other,self)
 
>>> a = int(5)
>>> 3 - a
-2
>>>

5.增量賦值運算
__iadd__(self.other)  定義賦值加法的行爲: +=

6.一元操作符
__neg__(self) 定義正號的行爲:+x
__pos__(self) 定義負號的行爲:-x
__abs__(self) 定義當被abs()調用時的行爲
__invert__(self) 定義按位求反的行爲:~x


7.其他運算符重載
__bool__              真值測試        測試對象是否爲真值:bool(x)
__repr__ __str__      打印,轉換      print  repr str
__contain__           成員測試        item in x
__getitem__           索引,切片      x[i] x[i:j] 沒有__iter__的for循環等
__setitem__           索引賦值        x[i]=值
__delitem__           索引和分片刪除  del x[i]
__len__               求長度          len(x)
__iter__ __next__     迭代            iter()  next()  for循環等

--------------------------------------------------------------------------------------------------------------------------------
常用特殊方法

方法                 功能說明
__init__()   構造函數,生成對象時調用
__del__()   析構函數,釋放對象時調用
__add__()   左
__sub__()   -
__mul__()   *
__div__()__truediv__() /.x使用.x使用
__floordiv__()   整除
__mod__()   %
__pow__()   **
__cmp__()   比較運算
__repr__()   打印、轉換
__setitem__()   按照索引賦值
__getitem__()   按照索引獲取值
__len__()   計算長度
__call__()   函數調用
__contains__ ()   測試是否包含某個元素
__eq__()、 __ne__()、__lt__()、 __le__()、__gt__()、__ge__()    == !=  <  <=  >  >=
__str__()   轉化爲字符串
__lshift__()   <<
__and__()   &
__or__()        |
__invert__()    ~
__iadd__()   +=
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章