內(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)的魔法方法
見上面的表格