Python進階:實例講解Python中的魔法函數(Magic Methods)

webnexus 7年前發布 | 14K 次閱讀 Python Python開發

什么是魔法函數?

所謂魔法函數(Magic Methods),是Python的一種高級語法,允許你在類中自定義函數(函數名格式一般為__xx__),并綁定到類的特殊方法中。比如在類A中自定義__str__()函數,則在調用str(A())時,會自動調用__str__()函數,并返回相應的結果。在我們平時的使用中,可能經常使用__init__函數和__del__函數,其實這也是魔法函數的一種。

魔法函數有什么作用?

魔法函數可以為你寫的類增加一些額外功能,方便使用者理解。舉個簡單的例子,我們定義一個“人”的類People,當中有屬性姓名name、年齡age。讓你需要利用sorted函數對一個People的數組進行排序,排序規則是按照name和age同時排序,即name不同時比較name,相同時比較age。由于People類本身不具有比較功能,所以需要自定義,你可以這么定義People類:

class People(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        return

    def __str__(self):
        return self.name + ":" + str(self.age)

    def __lt__(self, other):
        return self.name < other.name if self.name != other.name else self.age < other.age

print("\t".join([str(item) for item in sorted([People("abc", 18), People("abe", 19), People("abe", 12), People("abc", 17)])]))

上個例子中的__lt__函數即less than函數,即當比較兩個People實例時自動調用。

再舉個例子,實現一個可以任意深度賦值的字典類,如a[0] = 'value1'; a[1][2] = 'value2'; a[3][4][5] = 'value3'。這個和Python自帶的defaultdict還有些區別。簡單分析一下這個題目:普通的dict可以實現a[0]賦值,但是無法給a[1][2]直接賦值;后者賦值的過程大概為a.get(1).set(2, value),但我們不確定a[1]是否存在,所以很自然會想到要改寫dict類中的__getitem__()函數,當a[1]不存在時,聲明一個dict,并賦值給a[1]。代碼如下:

class MyDict(dict):
    def __setitem__(self, key, value):  # 該函數不做改動,只是為了輸出
        print("setitem:", key, value, self)
        super().__setitem__(key, value)
        return

    def __getitem__(self, item):                # 主要技巧在該函數
        print("getitem:", item, self)
        # 基本思路: a[1][2]賦值時 需要先取出a[1] 然后給a[1]的[2]賦值
        if item not in self:                    # 如果a[1]不存在
            temp = MyDict()                     # 則需要新建一個dict
            super().__setitem__(item, temp)     # 并使得a[1] = dict
            return temp                         # 返回a[1] 使得a[1][2] = value有效
        return super().__getitem__(item)        # 如果a[1]存在 則直接返回a[1]

# 使用例子:
test = MyDict()
test[0] = 'test'
test[1][2] = 'test1'
test[3][4][5] = 'test2'

Python中有哪些魔法函數?

Python中每個魔法函數都對應了一個Python內置函數或操作,比如__str__對應str函數,__lt__對應小于號<等。Python中的魔法函數可以大概分為以下幾類:

類的構造、刪除:

object.__new__(self, ...)
object.__init__(self, ...)
object.__del__(self)

二元操作符:

+ object.__add__(self, other)
-   object.__sub__(self, other)
*   object.__mul__(self, other)
//  object.__floordiv__(self, other)
/   object.__div__(self, other)
%   object.__mod__(self, other)
**  object.__pow__(self, other[, modulo])
<<    object.__lshift__(self, other)
>>    object.__rshift__(self, other)
&   object.__and__(self, other)
^   object.__xor__(self, other)
|   object.__or__(self, other)

擴展二元操作符:

+=    object.__iadd__(self, other)
-=  object.__isub__(self, other)
*=  object.__imul__(self, other)
/=  object.__idiv__(self, other)
//= object.__ifloordiv__(self, other)
%=  object.__imod__(self, other)
**= object.__ipow__(self, other[, modulo])
<<=   object.__ilshift__(self, other)
>>=   object.__irshift__(self, other)
&=  object.__iand__(self, other)
^=  object.__ixor__(self, other)
|=  object.__ior__(self, other)

一元操作符:

- object.__neg__(self)
+   object.__pos__(self)
abs()   object.__abs__(self)
~   object.__invert__(self)
complex()   object.__complex__(self)
int()   object.__int__(self)
long()  object.__long__(self)
float() object.__float__(self)
oct()   object.__oct__(self)
hex()   object.__hex__(self)
round() object.__round__(self, n)
floor() object__floor__(self)
ceil()  object.__ceil__(self)
trunc() object.__trunc__(self)

比較函數:

<  object.__lt__(self, other)
<=   object.__le__(self, other)
==  object.__eq__(self, other)
!=  object.__ne__(self, other)
>=   object.__ge__(self, other)
>    object.__gt__(self, other)

類的表示、輸出:

str() object.__str__(self) 
repr()  object.__repr__(self)
len()   object.__len__(self)
hash()  object.__hash__(self) 
bool()  object.__nonzero__(self) 
dir()   object.__dir__(self)
sys.getsizeof() object.__sizeof__(self)

類容器:

len() object.__len__(self)
self[key]   object.__getitem__(self, key)
self[key] = value   object.__setitem__(self, key, value)
del[key] object.__delitem__(self, key)
iter()  object.__iter__(self)
reversed()  object.__reversed__(self)
in操作    object.__contains__(self, item)
字典key不存在時   object.__missing__(self, key)

 

 

來自:https://zhuanlan.zhihu.com/p/24567545

 

 本文由用戶 webnexus 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!