2020年9月16日星期三

[課後作業] 第042講:魔法方法:算術運算|課後測試題及答案

[課後作業] 第042講:魔法方法:算術運算|課後測試題及答案




《零基礎入門學習Python》視頻下載地址:傳送門
*}XK_(~
測試題:n.版權屬於:bbs.fishc.com Ez
unG2ql+=
0.自Python2.2以後,對類和類型進行了統一,做法就是將int()、float()、str()、list()、tuple()這些BIF轉換為工廠函數。請問所謂的工廠函數,其實是什麼原理?N }Xrc
Ow`?Yms
fXq=C
1.當實例對象進行加法操作時,會自動調用什麼魔法方法?{|y}^SH Kg
2;dE*
z"qZ>-j
2.下邊代碼有問題嗎?(運行起來似乎沒出錯的說^_^)Wf)M`J!

"5G8E#)y*

  1. class Foo:
  2.         def foo(self):
  3.                 self.foo = "I love FishC.com!"
  4.                 return self.foo

  5. >>> foo = Foo()
  6. >>> foo.foo()
  7. 'I love FishC.com!'
複製代碼

5T%<g^
3.寫出下列算術運算符對應的魔法方法:Z%y*F
><xz-~a|w
運算符
對應的魔法方法
+

-

*

/

//

%

divmod(a, b)

**

<<

>>

&

^

|


sLJ`iqRh~
4.以下代碼說明Python支持什麼風格?>yT#]t{
@D b來自:bbs.fishc.com KF
  1. def calc(a, b, c):
  2.         return (a + b) * c

  3. >>> a = calc(1, 2, 3)
  4. >>> b = calc([1, 2, 3], [4, 5, 6], 2)
  5. >>> c = calc('love', 'FishC', 3)
  6. >>> print(a)
  7. 9
  8. >>> print(b)
  9. [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
  10. >>> print(c)
  11. loveFishCloveFishCloveFishC
複製代碼

-(#^P
動動手:
2Ne>mfE7
0.我們都知道在Python中,兩個字符串相加會自動拼接字符串,但遺憾的是兩個字符串相減卻拋出異常。因此,現在我們要求定義一個Nstr類,支持字符串的相減操作:A – B,從A中去除所有B的子字符串。@~`-Q{5,B
JY{ 6R
示例:DW #vz
  1. >>> a = Nstr('I love FishC.com!iiiiiiii')
  2. >>> b = Nstr('i')
  3. >>> a - b
  4. 'I love FshC.com!'
複製代碼

9(來自:bbs.fishc.com $*
1.移位操作符是應用於二進制操作數的,現在需要你定義一個新的類Nstr,也支持移位操作符的運算:
j}*.,P
  1. >>> a = Nstr('I love FishC.com!')
  2. >>> a << 3
  3. 'ove FishC.com!I l'
  4. >>> a >> 3
  5. 'om!I love FishC.c'
複製代碼

MDZ*}5If"A
2.定義一個類Nstr,當該類的實例對象間發生的加、減、乘、除運算時,將該對象的所有字符串的ASCII碼之和進行計算:^=* J?:OC"
cv6P!m
  1. >>> a = Nstr('FishC')
  2. >>> b = Nstr('love')
  3. >>> a + b
  4. 899
  5. >>> a - b
  6. 23
  7. >>> a * b
  8. 201918
  9. >>> a / b
  10. 1.052511415525114
  11. >>> a // b
  12. 1
複製代碼

3.請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!2C&zPowered by bbs.fishc.com
Powered by bbs.fishc.com A~!wujxk
回复您的答案即可查看參考答案!)版權屬於:bbs.fishc.com Wxt(uN
Vy%Qw=Y來自:bbs.fishc.com
_-m<3*ydX8
測試題答案:qo;&9L`{

本帖隱藏的內容

$K{OEo5
0.自Python2.2以後,對類和類型進行了統一,做法就是將int()、float()、str()、list()、tuple()這些BIF轉換為工廠函數。請問所謂的工廠函數,其實是什麼原理?
Lb09`sD
答:工廠函數,其實就是一個類對象。當你調用他們的時候,事實上就是創建一個相應的實例對象。m{Powered by bbs.fishc.com &c,#><V
-f|2F:mH)
  1. # a 和b 是工廠函數(類對象) int 的實例對象
  2. >>> a = int('123')
  3. >>> b = int('345')
  4. >>> a + b
  5. 468
複製代碼

q#`8*xw
1.當實例對象進行加法操作時,會自動調用什麼魔法方法?OJ|HETV
lK0)j
答:對象a和b相加時(a + b),Python會自動根據對象a的__add__魔法方法進行加法操作。`|2b}
BA"L+c
R}paS
2.下邊代碼有問題嗎?(運行起來似乎沒出錯的說^_^)CFhR(-來自:bbs.fishc.com IaP
b< y?U;1 "d
  1. class Foo:
  2.         def foo(self):
  3.                 self.foo = "I love FishC.com!"
  4.                 return self.foo

  5. >>> foo = Foo()
  6. >>> foo.foo()
  7. 'I love FishC.com!'
複製代碼

答:這絕對是一個溫柔的陷阱,這種BUG比較難以排查,所以一定要注意:類的屬性名和方法名絕對不能相同!如果代碼這麼寫,就會有一個難以排查的BUG出現了:b6W>h:sFo
la:]d$i0
  1. class Foo:
  2.         def __init__(self):
  3.                 self.foo = "I love FishC.com!"
  4.         def foo(self):
  5.                 return self.foo

  6. >>> foo = Foo()
  7. >>> foo.foo()
  8. Traceback (most recent call last):
  9.   File "<pyshell#21>", line 1, in <module>
  10.     foo.foo()
  11. TypeError: 'str' object is not callable
複製代碼

ME`QC*8
3.寫出下列算術運算符對應的魔法方法:BQh lMXn:1
版權屬於:bbs.fishc.com xCR&IE
運算符
對應的魔法方法
+
__add__(self, other)
-
__sub__(self, other)
*
__mul__(self, other)
/
__truediv__(self, other)
//
__floordiv__(self, other)
%
__mod__(self, other)
divmod(a, b)
__divmod__(a, b)
**
__pow__(self, other[, modulo])
<<
__lshift__(self, other)
>>
__rshift__(self, other)
&
__and__(self, other)
^
__xor__(self, other)
|
__or__(self, other)

b;XF0s1@hPowered by bbs.fishc.com
4.以下代碼說明Python支持什麼風格?9lPowered by bbs.fishc.com 3Okb_K
3@0]qB:
  1. def calc(a, b, c):
  2.         return (a + b) * c

  3. >>> a = calc(1, 2, 3)
  4. >>> b = calc([1, 2, 3], [4, 5, 6], 2)
  5. >>> c = calc('love', 'FishC', 3)
  6. >>> print(a)
  7. 9
  8. >>> print(b)
  9. [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
  10. >>> print(c)
  11. loveFishCloveFishCloveFishC
複製代碼

答:說明Python支持鴨子類型(duck typing)風格。A>2I3iJ?B
Rjw1_3
詳見:【擴展閱讀】鴨子類型(duck typing)X?St-uA"K

kIK-#N8T1"
%v@_-K>版權屬於:bbs.fishc.com b
動動手答案:

本帖隱藏的內容

F2lRpkHq
0.我們都知道在Python中,兩個字符串相加會自動拼接字符串,但遺憾的是兩個字符串相減卻拋出異常。因此,現在我們要求定義一個Nstr類,支持字符串的相減操作:A – B,從A中去除所有B的子字符串。
mt&*來自:bbs.fishc.com Wn<Q
示例:.|}$>
  1. >>> a = Nstr('I love FishC.com!iiiiiiii')
  2. >>> b = Nstr('i')
  3. >>> a - b
  4. 'I love FshC.com!'
複製代碼

答:只需要重載__sub__魔法方法即可。G@k3q
oq%z6H
  1. class Nstr(str):
  2.     def __sub__(self, other):
  3.         return self.replace(other, '')
複製代碼

來自:bbs.fishc.com ;ZS%D:F
1.移位操作符是應用於二進制操作數的,現在需要你定義一個新的類Nstr,也支持移位操作符的運算:};=WN3u8n #
'.g?H
  1. >>> a = Nstr('I love FishC.com!')
  2. >>> a << 3
  3. 'ove FishC.com!I l'
  4. >>> a >> 3
  5. 'om!I love FishC.c'
複製代碼

答:只需要重載__lshift__和__rshift__魔法方法即可。U;<Lfr^#
cPuw):
  1. class Nstr(str):
  2.     def __lshift__(self, other):
  3.         return self[other:] + self[:other]

  4.     def __rshift__(self, other):
  5.         return self[-other:] + self[:-other]
複製代碼

N8ihmO=
2.定義一個類Nstr,當該類的實例對象間發生的加、減、乘、除運算時,將該對象的所有字符串的ASCII碼之和進行計算:Grus`g
w.L4NY%
  1. >>> a = Nstr('FishC')
  2. >>> b = Nstr('love')
  3. >>> a + b
  4. 899
  5. >>> a - b
  6. 23
  7. >>> a * b
  8. 201918
  9. >>> a / b
  10. 1.052511415525114
  11. >>> a // b
  12. 1
複製代碼

代碼清單:u$TOVh?Z
  1. class Nstr:
  2.     def __init__(self, arg=''):
  3.         if isinstance(arg, str):
  4.             self.total = 0
  5.             for each in arg:
  6.                 self.total += ord(each)
  7.         else:
  8.             print("參數錯誤!")

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

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

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

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

  17.     def __floordiv__(self, other):
  18.         return self.total // other.total
複製代碼

當然,你還可以這樣做::04Powered by bbs.fishc.com h~R-
  1. class Nstr(int):
  2.     def __new__(cls, arg=0):
  3.         if isinstance(arg, str):
  4.             total = 0
  5.             for each in arg:
  6.                 total += ord(each)
  7.             arg = total
  8.         return int.__new__(cls, arg)
複製代碼

3.請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!

小甲魚希望你認真對待作業就像你希望小甲魚推出高質量視頻一樣渴望^_^

在Python2.2之前,類和類型是分開的,在Python2.2之後,作者試圖對這兩個東西進行統一,做法就是將int()、float()、str()、list()、tuple( )這些BIF轉換為工廠函數,那什麼是工廠函數呢?
我們試圖演示一下:
  1. >>> type(len)
  2. <class 'builtin_function_or_method'>
len()是一個普通的內置函數,返回類似也告訴了我們這一點,但是
  1. >>> type(int)
  2. <class 'type'>
  3. >>> type(list)
  4. <class 'type'>
然後我們發現:
  1. >>> class C:
  2. pass
  3. >>> type(C)
  4. <class 'type'>
所以,工廠函數就是類對象。
Python的魔法方法還提供了讓你自定義對象的數值處理,通過對我們這些魔法方法進行重寫,你可以自定義任何對象間的算術運算。
__add__(self, other)
定義加法的行為:+
__sub__(self, other)
定義減法的行為:-
__mul__(self, other)
定義乘法的行為:*
__truediv__(self, other)
定義真除法的行為:/
__floordiv__(self, other)
定義整數除法的行為://
__mod__(self, other)
定義取模算法的行為:%
__ divmod __(self, other)
定義當被 divmod () 調用時的行為,divmod(a, b)返回一個元組:(a//b, a%b)
__pow__(self, other[, modulo])
定義當被power() 調用或** 運算時的行為
__ lshift __(self, other)
定義按位左移位的行為:<<
__rshift__(self, other)
定義按位右移位的行為:>>
__and__(self, other)
定義按位與操作的行為:&
__xor__(self, other)
定義按位異或操作的行為:^
__or__(self, other)
定義按位或操作的行為:|
例如:
  1. >>> class New_int(int):
  2. def __add__(self, other):
  3. return int.__sub__(self, other)
  4. def __sub__(self, other):
  5. return int.__add__(self, other)
  6. >>> a = New_int(3)
  7. >>> b = New_int(5)
  8. >>> a + b
  9. -2
  10. >>> a - b
  11. 8

發現了沒,我在這裡對原有int 的加法和減法進行了改寫,把加法變為減法,減法變為加法。

0 留言:

發佈留言