第四十二課:魔法方法:算術(shù)運(yùn)算

內(nèi)容來源于網(wǎng)絡(luò)岩梳,本人只是在此稍作整理,如有涉及版權(quán)問題猿涨,歸小甲魚官方所有握童。

練習(xí)題(來自小甲魚官方論壇)

0.自從Python 2.2以后,對(duì)類和類型進(jìn)行了統(tǒng)一叛赚,做法就是將int()澡绩、float()、str()俺附、list()肥卡、tuple()這些BIF轉(zhuǎn)換為工廠函數(shù)。請(qǐng)問所謂的工廠函數(shù)事镣,其實(shí)是什么原理步鉴?

答:工廠函數(shù),其實(shí)就是一個(gè)類對(duì)象璃哟。當(dāng)你調(diào)用他們的時(shí)候氛琢,事實(shí)上就是創(chuàng)建一個(gè)相應(yīng)的實(shí)例對(duì)象。

# a和b是工廠函數(shù)(類對(duì)象)int的實(shí)例對(duì)象
>>> a = int('123')
>>> b = int('345')
>>> a + b
468

1.當(dāng)實(shí)例對(duì)象進(jìn)行加法操作時(shí)随闪,會(huì)自動(dòng)調(diào)用什么魔法方法阳似?

答:對(duì)象a和b相加時(shí)(a+b),Python會(huì)自動(dòng)根據(jù)對(duì)象a的__ add__()魔法方法進(jìn)行相加操作铐伴。


2.下邊代碼有問題嗎撮奏?(運(yùn)行起來好像沒報(bào)錯(cuò))

>>> class Foo:
    def foo(self):
        self.foo = "I love FishC.com!"
        return self.foo
      
>>> foo = Foo()   
>>> foo.foo()     
'I love FishC.com!'

答:這絕對(duì)是一個(gè)溫柔的陷阱,這種BUG比較難以排查盛杰,所以一定要注意:類的屬性名和方法名絕對(duì)不能相同挽荡!如果代碼這么寫,就會(huì)有一個(gè)難以排查的BUG出現(xiàn)了:

>>> class Foo:
      def __init__(self):
          self.foo = "I love FishC.com!"
      def foo(self):
          return self.foo
      
>>> foo = Foo()   
>>> foo.foo()     
Traceback (most recent call last):
  File "<pyshell#120>", line 1, in <module>
    foo.foo()
TypeError: 'str' object is not callable  # 不能調(diào)用

注意:如果類中的方法名和屬性名相同即供,屬性會(huì)覆蓋方法定拟。


3.給出以下算數(shù)運(yùn)算符對(duì)應(yīng)的魔法方法:

運(yùn)算符 對(duì)應(yīng)的魔法方法 中文注釋
+ __ add__(self, other) 加法
- __ sub__(self, other) 減法
* __ mul__(self, other) 乘法
/ __ truediv__(self, other) 真除法
// __ floordiv__(self, other) 整數(shù)除法
% __ mod__(self, other) 取余除法
divmod(a, b) __ divmod__(self, other) 把除數(shù)和余數(shù)運(yùn)算結(jié)果結(jié)合
** __ pow__(self, other[,modulo]) self的other次方再對(duì)modulo取余
<< __ lshift__(self, other) 按位左移
>> __ rshift__(self, other) 按位右移
& __ and__(self, other) 按位與操作
^ __ xor__(self, other) 按位異或操作(同為0,異為1)
__ or__(self, other) 按位或操作(有1則1)

4.以下代碼說明Python支持什么風(fēng)格?

>>> def calc(a, b, c):
      return (a + b) * c
      
>>> a = calc(1, 2, 3)     
>>> b = calc([1, 2, 3], [4, 5, 6], 2)     
>>> c = calc('love', 'FishC', 3)      
>>> print(a)      
9
>>> print(b)      
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
>>> print(c)      
loveFishCloveFishCloveFishC

答:說明Python支持鴨子類型(duck typing)風(fēng)格青自。我們并不關(guān)心對(duì)象是什么類型株依,到底是不是鴨子,只關(guān)心行為延窜。


編程題

0.我們都知道在Python中恋腕,兩個(gè)字符串相加會(huì)自動(dòng)拼接字符串,但遺憾的是兩個(gè)字符串相減卻拋出異常逆瑞,因此荠藤,現(xiàn)在我們要求定義一個(gè)Nstr類,支持字符串的相減操作:A - B获高,從A中去除所有B的子字符串哈肖。

實(shí)例:

>>> a = Nstr('I love FishC.com!iiiiiiiiiiiii')
>>> b = Nstr('i')
>>> a - b
'I love FshC.com!'

答:只需要重載__ sub__魔法方法即可。

>>> class Nstr(str):
      def __sub__(self, other):
          return self.replace(other, '')
      
>>> a = Nstr("anckjcaevjeoicsvmskvbnsvm;alc,wvwenvoslv,eos")
>>> b = Nstr("a")     
>>> a - b     
'nckjcevjeoicsvmskvbnsvm;lc,wvwenvoslv,eos'

1.移位操作符是應(yīng)用于二進(jìn)制操作數(shù)的念秧,現(xiàn)在需要你定義一個(gè)新的類Nstr淤井,也支持移位操作符的運(yùn)算。

實(shí)例:

>>> a = Nstr('I love FishC.com!')
>>> a << 3
'ove FishC.com!I l'
>>> a >> 3
'I love FishC.com!'

答:只需要重載__ lshift__ 和 __ rshift__魔法方法即可摊趾。

>>> class Nstr(str):
      def __lshift__(self, other):
          return self[other:] + self[:other]
      def __rshift__(self, other):
          return self[-other:] + self[:-other] # 感覺代碼有問題

2.定義一個(gè)類Nstr币狠,當(dāng)該類的實(shí)例對(duì)象間發(fā)生的加、減砾层、乘漩绵、除運(yùn)算時(shí),將該對(duì)象的所有字符串的ASCII碼之和進(jìn)行運(yùn)算肛炮。

class Nstr:
    def __init__(self, arg=''):
        if isinstance(arg, str):
            self.total = 0
            for each in arg:
                self.total += ord(each)
        else:
            print("參數(shù)錯(cuò)誤")

    def __add__(self, other):
        return self.total + other.total

    def __sub__(self, other):
        return self.total - other.total

    def __mul__(self, other):
        return self.total * other.total

    def __truediv__(self, other):
        return self.total / other.total

    def __floordiv__(self, other):
        return self.total // other.total


a = Nstr('abc')
b = Nstr('def')
print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(a // b)

輸出

597
-9
89082
0.9702970297029703
0

3.請(qǐng)寫下這一節(jié)課你學(xué)習(xí)到的內(nèi)容:格式不限渐行,回憶并復(fù)述是加強(qiáng)記憶的好方式!

  • 工廠函數(shù):其實(shí)就是一個(gè)類對(duì)象铸董,被調(diào)用的時(shí)候,事實(shí)上就是創(chuàng)建一個(gè)相應(yīng)的實(shí)例對(duì)象肴沫。就是:
>>> type(int)
<class 'type'>
>>> type(dir)
<class 'type'>
>>> type(list)
<class 'type'>
>>> class C:
       pass
>>> type(C)
<class 'type'>
  • 算數(shù)運(yùn)算相關(guān)的魔法方法
    見上面的表格

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末粟害,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子颤芬,更是在濱河造成了極大的恐慌悲幅,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件站蝠,死亡現(xiàn)場(chǎng)離奇詭異汰具,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)菱魔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門留荔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人澜倦,你說我怎么就攤上這事聚蝶〗芗耍” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵碘勉,是天一觀的道長巷挥。 經(jīng)常有香客問我,道長验靡,這世上最難降的妖魔是什么倍宾? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮胜嗓,結(jié)果婚禮上高职,老公的妹妹穿的比我還像新娘。我一直安慰自己兼蕊,他們只是感情好初厚,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著孙技,像睡著了一般产禾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牵啦,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天亚情,我揣著相機(jī)與錄音,去河邊找鬼哈雏。 笑死楞件,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裳瘪。 我是一名探鬼主播土浸,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼彭羹!你這毒婦竟也來了黄伊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤派殷,失蹤者是張志新(化名)和其女友劉穎还最,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毡惜,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拓轻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了经伙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扶叉。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辜梳,到底是詐尸還是另有隱情粱甫,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布作瞄,位于F島的核電站茶宵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宗挥。R本人自食惡果不足惜乌庶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望契耿。 院中可真熱鬧瞒大,春花似錦、人聲如沸搪桂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踢械。三九已至酗电,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間内列,已是汗流浹背撵术。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留话瞧,地道東北人嫩与。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像交排,于是被迫代替她去往敵國和親划滋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容