課時42:魔法方法:算術運算
- 2020 年 1 月 19 日
- 筆記
目錄:
一、算術運算符
二、課時41課後習題及答案
現在來講一個新名詞:工廠函數。Python2.2以後,對類和類型進行了統一,做法就是將int()、float()、str()、list()、tuple()這些BIF轉換為工廠函數:
>>> type(len) <class 'builtin_function_or_method'> >>> type(int) <class 'type'> >>> type(dir) <class 'builtin_function_or_method'> >>> type(list) <class 'type'>
看到沒有,普通的BIF應該是<class 'builtin_function_or_method'>,而工廠函數則是<class 'type'>。大家有沒有覺得<class 'type'>很眼熟,沒錯啦,如果定義一個類:
>>> class C: pass >>> type(C) <class 'type'>
它的類型也是type類型,也就是類對象,其實所謂的工廠函數,其實就是一個類對象。當你調用它們的時候,事實上就是創建一個相應的實例對象:
>>> a = int('123') >>> b = int('345') >>> a + b 468
現在你是不是豁然發現:原來對象是可以進行計算的!其實你早該發現這個問題了,Python中無處不對象,當在求a + b等於多少的時候,事實上Python就是在將兩個對象進行相加操作。Python的魔法方法還提供了自定義對象的數值處理,通過下面這些魔法方法的重寫,可以自定義任何對象間的算術運算。
******************
一、算術運算符
******************
表中列舉了算術運算相關的魔法方法。
__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() 調用或 ** 運算時的行為 __lshift__(self, other) 定義按位左移位的行為:<< __rshift__(self, other) 定義按位右移位的行為:>> __and__(self, other) 定義按位與操作的行為:& __xor__(self, other) 定義按位異或操作的行為:^ __or__(self, other) 定義按位或操作的行為:|
舉個例子,下面定義一個比較特立獨行的類:
>>> class New_int(int): def __add__(self,other): return int.__sub__(self,other) def __sub__(self,other): return int.__add__(self,other) >>> a = New_int(3) >>> b = New_int(5) >>> a + b -2 >>> a - b 8
倘若你想自己寫程式碼,不想通過調用Python默認的方案行不行?答案是肯定的,但是要格外小心。
>>> class Try_int(int): def __add__(self,other): return self + other def __sub__(self,other): return self - other >>> a = Try_int(1) >>> b = Try_int(3) >>> a + b Traceback (most recent call last): File "<pyshell#51>", line 1, in <module> a + b File "<pyshell#48>", line 3, in __add__ return self + other File "<pyshell#48>", line 3, in __add__ return self + other File "<pyshell#48>", line 3, in __add__ return self + other [Previous line repeated 990 more times] RecursionError: maximum recursion depth exceeded
為什麼會陷入無限遞歸呢?問題出在這裡:
def __add__(self,other): return self + other
當對象涉及加法操作時,自動調用魔法方法__add__(),但看看上邊的魔法方法寫的是什麼?寫的是return self + other,也就是返回對象本身加另外一個對象,這不就又自動觸發調用__add__()方法了嗎?這樣就形成了無限遞歸。所以,要像下面這樣寫就不會觸發無限遞歸了:
>>> class New_int(int): def __add__(self,other): return int(self) + int(other) def __sub__(self,other): return int(self) - int(other) >>> a = New_int(1) >>> b = New_int(3) >>> a + b 4
當對象進行相關的算術運算,自然而然就會自動觸發對應的魔法方法。
通過對魔法方法的重寫,你完全可以讓Python根據你的意願去執行:
>>> class int(int): def __add__(self,other): return int.__sub__(self,other) >>> a = int('5') >>> b = int('3') >>> a + b 2
當然,這樣做在邏輯上是說不過去的…… emmmm
*******************************
二、課時41課後習題及答案
*******************************















