Python--特殊方法
阿新 • • 發佈:2020-12-05
不管在哪種框架下寫程式,都會花費大量時間去實現那些會被框架本身呼叫的方法。
Python 直譯器碰到特殊的句法時,會使用特殊方法去啟用一些基本的物件操作,這些特殊方法的名字以兩個下劃線開頭,以兩個下劃線結尾
比如 obj[key] 的背後就是 __getitem__ 方法,為了能求得my_collection[key] 的值,直譯器實際上會呼叫my_collection.__getitem__(key)。
比如 for i in x: 這個語句,背後其實用的是iter(x),而這個函式的背後則是 x.__iter__() 方法。當然前提是這個方法在 x 中被實現了。
特殊方法的存在是為了被 Python 直譯器呼叫的,你自己並不需要呼叫它們。
通過實現特殊方法,自定義資料型別可以表現得跟內建型別一樣,從而讓我們寫出更具表達力的程式碼。
一、如何使用特殊方法
定義一個簡單的二維向量類:
些方法。
__repr__
如果沒有實現 __repr__,當我們在控制檯裡列印一個向量的例項時,得到的字串可能會是 <Vector object at 0x10e100070>。
__repr__ 和 __str__ 的區別在於,後者是在 str() 函式被使用,或是在用 print 函式列印一個物件的時候才被呼叫的,並且它返回的字串對終端使用者更友好。
如果你只想實現這兩個特殊方法中的一個,__repr__ 是更好的選擇,因為如果一個物件沒有 __str__ 函式,而 Python 又需要呼叫它的時候,直譯器會用 __repr__ 作為替代。
二、特殊方法一覽
字串 / 位元組序列表示形式
__repr__、__str__、__format__、__bytes__
數值轉換
__abs__、__bool__、__complex__、__int__、__float__、__hash__、__index__
集合模擬
__len__、__getitem__、__setitem__、__delitem__、__contains__
迭代列舉
__iter__、__reversed__、__next__
可呼叫模擬
__call__
上下文管理
__enter__、__exit__
例項建立和銷燬
__new__、__init__、__del__
屬性管理
__getattr__、__getattribute__、__setattr__、__delattr__、__dir__
屬性描述符
__get__、__set__、__delete__
跟類相關的服務
__prepare__、__instancecheck__、__subclasscheck__
一元運算子
__neg__ -、__pos__ +、__abs__ abs()
眾多比較運算子
__lt__ <、__le__ <=、__eq__ ==、__ne__ !=、__gt__ >、__ge__ >=
算術運算子
__add__ +、__sub__ -、__mul__ *、__truediv__ /、__floordiv__ //、__mod__ %、__divmod__
divmod()、__pow__ ** 或pow()、__round__ round()
反向算術運算子
__radd__、__rsub__、__rmul__、__rtruediv__、__rfloordiv__、__rmod__、__rdivmod__、__rpow__
增量賦值算術運算子
__iadd__、__isub__、__imul__、__itruediv__、__ifloordiv__、__imod__、__ipow__
位運算子
__invert__ ~、__lshift__ <<、__rshift__ >>、__and__ &、__or__ |、__xor__ ^
反向位運算子
__rlshift__、__rrshift__、__rand__、__rxor__、__ror__
增量賦值位運算子
__ilshift__、__irshift__、__iand__、__ixor__、__ior__
from math import hypot這些方法(除了 __init__)並不會在這個類自身的程式碼中使用。即便其他程式要使用這個類的這些方法,也不會直接呼叫它們,一般只有 Python 直譯器會頻繁地直接呼叫這
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y
def __repr__(self): return 'Vector(%r, %r)' % (self.x, self.y)
def __abs__(self): return hypot(self.x, self.y) def__bool__(self): return bool(abs(self)) def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) def __mul__(self, scalar): return Vector(self.x * scalar, self.y * scalar)