在python2.2之前類與類型分開
類:封裝(屬性+方法)
類型:整型、浮點型、字符型、字符串型
但之後作者對這倆統一了
將int()、str()、list()這些BIF轉化成了工廠函數。
int()與類d的class是一樣的,可以把工廠函數看成類,返回實例對象
type(int)
<class 'type'>
class d:
... pass
...
type(d)
<class 'type'>
將類int()進行實例化
a = int('123')
b = int('456')
a+b
579
以前上面的語句是將字符串類型改爲整型
現在則是將類int()實例化爲a,而“123‘’則是傳入的參數
語句:a+b,實際上是對象之間的操作
python專門使用魔法方法定義了對象之間的操作
例如:當檢測到對象之間用+號操作時,自動調用int()類中的__add__方法(魔法方法,在需要的時候自動被調用,就像__init__)
下面創建新的類來繼承int()的所有方法,然後通過改寫__add__方法來讓+號不執行相加操作,反而執行相減操作
class re_int(int):
def __add__(self, other): # 檢測到對象間“+”號,自動執行該方法
return int.__sub__(self, other) # 返回值爲:int()類中的相減操作
def __sub__(self, other): # 檢測到對象間“-”號,自動執行該方法
return int.__add__(self, other) # 返回值爲:int()類中的相加操作
a = re_int('5')
b = re_int('3')
print(a + b)
2 # 運行結果
如此,我們在類re_int()中交換了符號“+”與符號“-”的作用,使由類產生的實例化對象a與b在執行符號:“+”與“-”的操作時並不像通常認知的那樣。
我們彷彿深入到了更加底層的代碼,上帝之手像你召喚喚喚喚喚!!!
下面讓我們來康康父類int()中的魔法方法是如何實現的:
(dir(類名):查看類中所有方法名和屬性名)
(help(類名.方法名):查看類中方法)
help(int.__add__)
Help on wrapper_descriptor:
__add__(self, value, /)
Return self+value.
help(int.__sub__)
Help on wrapper_descriptor:
__sub__(self, value, /)
Return self-value.
上面我們看到了int()類中add方法的實現過程
如果將我們的re_int類不繼承int而是自己定義add方法能實現實例對象的加法運算嗎?
class re_int(int):
def __add__(self, other,/): # 檢測到對象間“+”號,自動執行該方法
return self+other # 返回值爲:int()類中的相減操作
def __sub__(self, other,/): # 檢測到對象間“-”號,自動執行該方法
return self-other # 返回值爲:int()類中的相加操作
a = re_int('5')
b = re_int('3')
print(a+b)
運行結果發現超出做大遞歸數
Traceback (most recent call last):
File "D:/FishC/作業/41_48_魔法方法/11.py", line 17, in <module>
print(a+b)
File "D:/FishC/作業/41_48_魔法方法/11.py", line 8, in __add__
return self+other # 返回值爲:int()類中的相減操作
File "D:/FishC/作業/41_48_魔法方法/11.py", line 8, in __add__
return self+other # 返回值爲:int()類中的相減操作
File "D:/FishC/作業/41_48_魔法方法/11.py", line 8, in __add__
return self+other # 返回值爲:int()類中的相減操作
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded
要想正確運行可以在返回前面加上int(),這樣返回的是整型的相加
class re_int(int):
def __add__(self, other,/): # 檢測到對象間“+”號,自動執行該方法
return int(self)+int(other) # 返回值爲:int()類中的相減操作
def __sub__(self, other,/): # 檢測到對象間“-”號,自動執行該方法
return int(self)-int(other) # 返回值爲:int()類中的相加操作
a = re_int('5')
b = re_int('3')
print(a+b)
例子1:
兩個字符串相加會自動拼接字符串,但遺憾的是兩個字符串相減卻拋出異常。
因此,現在我們要求定義一個 Nstr 類,支持字符串的相減操作:
A – B,從 A 中去除所有 B 的子字符串
class Nstr(str):
def __sub__(self, other):
for each in other:
if each in self:
self = self.replace(each, '')
return str(self)
運行結果:
Nstr類繼承str類的所有屬性和方法:
檢測到減號自動調用__sub__魔法方法
(雖然str類中沒有__sub__方法,但是子類Nstr產生的實例遇到“-”號仍然會自動運行__sub__方法)
self是a,other是b
(a與b都是同一個類產生的對象,所以能調用共同的類方法進行操作)
>>> a = Nstr('I love FishC.com!iiiiiiii')
>>> b = Nstr('i')
>>> print(a - b)
I love FshC.com!
例子2:
#定義一個類 Nstr
#當該類的實例對象間發生的加、減、乘、除運算時
#將該對象的所有字符串的 ASCII 碼之和進行計算
#查看ASCII: ord(字符)
class Nstr(str):
def __add__(self, other): # 遇到符號:+ 自動運行魔法方法__add__(NB)
s1 = 0
s2 = 0
for each in self:
s1 += int(ord(each))
for each in other:
s2 += int(ord(each))
return s1 + s2
def __sub__(self, other):
s1 = 0
s2 = 0
for each in self:
s1 += int(ord(each))
for each in other:
s2 += int(ord(each))
return s1 - s2
def __mul__(self, other):
s1 = 0
s2 = 0
for each in self:
s1 += int(ord(each))
for each in other:
s2 += int(ord(each))
return s1 * s2
def __truediv__(self, other):
s1 = 0
s2 = 0
for each in self:
s1 += int(ord(each))
for each in other:
s2 += int(ord(each))
return s1 / s2
運行結果:
>>> a = Nstr('FishC')
>>> b = Nstr('love')
print(a+b,a-b,a*b,a/b)
899 23 201918 1.052511415525114