python 魔法方法(學習過程的筆記)
有小夥伴會問,什麽是python的魔法方法,python的魔法方法有什麽用呢,
它們在面向對象的Python的處處皆是。它們是一些可以讓你對類添加“魔法”的特殊方法。 它們經常是兩個下劃線包圍來命名的。
我感覺魔法方法很牛逼的,
目前我們常見的魔法方法大致可分為以下幾類:
- 構造與初始化
- 類的表示
- 訪問控制
- 比較操作
- 容器類操作
- 可調用對象
- Pickling序列化
在我們寫python中最常見的就是__init__,這是python的構造方法,這是初始化對象,定義一個對象的初始化的值,__new__ 這個我們在實際的很少用到吧, 不過在一些開源的框架到我們能用到這個,__new__返回值是一個實例,
__del__
這個方法代表析構方法,也就是在對象被垃圾回收時被調用。但是請註意,執行del x
不一定會執行此方法
__str__
/__repr__
這兩個魔法方法一般會放到一起進行講解,它們的主要差別為:
__str__
強調可讀性,而__repr__
強調準確性/標準性__str__
的目標人群是用戶,而__repr__
的目標人群是機器,它的結果是可以被執行的%s
調用__str__
方法,而%r
調用__repr__
方法
__setattr__
通過此方法,對象可在在對屬性進行賦值時進行控制,所有的屬性賦值都會經過它。
一般常用於對某些屬性賦值的檢查校驗邏輯,例如age
不能小於0,否則認為是非法數據等等。
__getattr__
很多同學以為此方法是和__setattr__
完全對立的,其實不然!
這個方法只有在訪問某個不存在的屬性時才會被調用,看上面的例子,由於gender
屬性在賦值時,忽略了此字段的賦值操作,所以此屬性是沒有被成功賦值給對象的。當訪問這個屬性時,__getattr__
被調用,返回unknown
。
__del__
刪除對象的某個屬性時,此方法被調用。一般常用於某個屬性必須存在,否則無法進行後續的邏輯操作,會重寫此方法,對刪除屬性邏輯進行檢查和校驗。
__getattribute__
這個方法我們很少用到,它與__getattr__
很容易混淆。它與前者的區別在於:
__getattr__
__getattribute__
訪問任意屬性被調用
__getattr__
只針對屬性訪問,__getattribute__
不僅針對所有屬性訪問,還包括方法調用
__iter__
執行for x in obj
時觸發執行,用於叠代容器內的元素。
__contains__
執行x in obj
時觸發執行,用於判斷某個元素是否存在於容器中。
__reversed__
執行reversed(obj)
時觸發執行,用於反轉容器的元素,具體的反轉邏輯可自己實現。
反射
__nstancecheck__(self, instance)
:檢查一個實例是否是你定義類中的一個實例__ubclasscheck__(self, subclass)
:檢查一個類是否是你定義類的子類
數值操作符
就像你可以使用比較操作符來比較類的實例,你也可以定義數值操作符的行為。固定好你的安全帶,這樣的操作符真的有很多。看在組織的份上,我把它們分成了五類:一元操作符,常見算數操作符,反射算數操作符,增強賦值操作符,和類型轉換操作符。
一元操作符
一元操作符只有一個操作符。
- __pos__(self)
實現取正操作,例如 +some_object。
-
__neg__(self)
實現取負操作,例如 -some_object。
-
__abs__(self)
實現內建絕對值函數 abs() 操作。
-
__invert__(self)
實現取反操作符 ~。
-
__round__(self, n)
實現內建函數 round() ,n 是近似小數點的位數。
-
__floor__(self)
實現 math.floor() 函數,即向下取整。
-
__ceil__(self)
實現 math.ceil() 函數,即向上取整。
-
__trunc__(self)
實現 math.trunc() 函數,即距離零最近的整數。
常見算數操作符
現在,我們來看看常見的二元操作符(和一些函數),像+,-,*之類的,它們很容易從字面意思理解。
-
__add__(self, other)
實現加法操作。
-
__sub__(self, other)
實現減法操作。
-
__mul__(self, other)
實現乘法操作。
-
__floordiv__(self, other)
實現使用 // 操作符的整數除法。
-
__div__(self, other)
實現使用 / 操作符的除法。
-
__truediv__(self, other)
實現 _true_ 除法,這個函數只有使用 from __future__ import division 時才有作用。
-
__mod__(self, other)
實現 % 取余操作。
-
__divmod__(self, other)
實現 divmod 內建函數。
-
__pow__
實現 ** 操作符。
-
__lshift__(self, other)
實現左移位運算符 << 。
-
__rshift__(self, other)
實現右移位運算符 >> 。
-
__and__(self, other)
實現按位與運算符 & 。
-
__or__(self, other)
實現按位或運算符 | 。
-
__xor__(self, other)
實現按位異或運算符 ^ 。
class DictDemo: def __init__(self,key,value): self.dict={} self.dict[key]=value def __getitem__(self,key): return self.dict[key] def __setitem__(self,key,value): self.dict[key]="key‘s value is %s"%value def __len__(self): return (len(self.dict)) dictDemo=DictDemo(‘key0‘,‘value1‘) print(dictDemo[‘key0‘]) dictDemo[‘key1‘]=‘beijing‘ print(dictDemo[‘key1‘]) print(len(dictDemo)) class word(str): def __eq__(self,other): return len(self)==len(other) w1=word(‘idshfisdojf‘) w2=word(‘sadsadas‘) print(w1==w2) print(len(w1)) class Apple(object): def __init__(self,name,size): self.name=name self.size=size def __str__(self): return ‘name is {}: size is {}‘.format(self.name,self.size) print(Apple(‘liwanlei‘,‘100‘))
class Person(object): def __init__(self,name,age): self.name=name self.age=age def __str__(self): return ‘name :%s, age:%s‘%(self.name,self.age) def __repr__(self): return "Person( ‘%s‘%s)"%(self.name,self.age) person=Person(‘leizi‘,‘18‘) print(str(person))#name :leizi, age:18 print(repr(person))#Person( ‘leizi‘18)
python 魔法方法(學習過程的筆記)