2020年9月16日星期三

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

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




《零基礎入門學習Python》視頻下載地址:傳送門@)Cvc
br:iL4y
測試題:{1BPowered by bbs.fishc.com Ao
t^gk1F)S[<
0.對象相加(a + b),如果a對像有__add__方法,請問b對象的__radd__會被調用嗎?
xj3WLG
tC,w(*F^9
1. Python什麼時候會調用到反運算的魔法方法?^j1k)
D_Powered by bbs.fishc.com 8$EeL{*
L5i版權屬於:bbs.fishc.com h
2.請問如何在繼承的類中調用基類的方法?^=?6]o"
來自:bbs.fishc.com o7lc$kn
+.}版權屬於:bbs.fishc.com >]6J
3.如果我要繼承的基類是動態的(有時候是A,有時候是B),我應該如何部署我的代碼,以便基類可以隨意改變。Powered by bbs.fishc.com 74Ab
來自:bbs.fishc.com 9j2.
+sxVLF'o~1
4.嘗試自己舉一個例子說明如何使用類的靜態屬性。(一定要自己先動手再看答案哦^_^)
3H^x%5
glrow來自: bbs.fishc.com f`
5.嘗試自己舉例說明如何使用類的靜態方法,並指出使用類的靜態方法有何有點和需要注意的地方?(一定要自己先動手再看答案哦^_^)5*2CD.08~F

i3"來自: bbs.fishc.com 9]z`
n Q]YS0B
動動手:
0oHKA<Ie
0.定義一個類,當實例化該類的時候,自動判斷傳入了多少個參數,並顯示出來:@}!:b
K_|VO<"`

  1. >>> c = C()
  2. 並沒有傳入參數
  3. >>> c = C(1, 2, 3)
  4. 傳入了3 個參數,分別是:1 2 3
複製代碼

ztD`3@9T*
1.定義一個單詞(Word)類繼承自字符串,重寫比較操作符(參考自學:Python魔法方法詳解),當兩個Word類對象進行比較時,根據單詞的長度來進行比較大小。權屬於:bbs.fishc.com x!.fw
5tirj(<,g{
加分要求:實例化時如果傳入的是帶空格的字符串,則取第一個空格前的單詞作為參數。Iv] ;W^)
>Powered by bbs.fishc.com Jg]Zp)IY


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


回复您的答案即可查看參考答案!O_0Ju!6d]@
$Ag'Nk(c

測試題答案:KG'jB!PN

本帖隱藏的內容

)(Czhg4~^
0.對象相加(a + b),如果a對像有__add__方法,請問b對象的__radd__會被調用嗎?
xI=U]4v
答:不會!}oYX$4
sHIFA?
實驗如下:DH)eE0=
  1. >>> class Nint(int):
  2.         def __radd__(self, other):
  3.                 print("__radd__ 被調用了!")
  4.                 return int.__add__(self, other)

  5. >>> a = Nint(5)
  6. >>> b = Nint(3)
  7. >>> a + b
  8. 8
  9. >>> 1 + b
  10. __radd__ 被調用了!
  11. 4
複製代碼

4BD5+
1. Python什麼時候會調用到反運算的魔法方法?O>+LvD#b`
+OY0{dLG2
答:例如a + b,如果a對象的__add__方法沒有實現或者不支持相應的操作,那麼Python就會自動調用b的__radd__方法。
6_wzDYfgP}
wT;$ #=W
2.請問如何在繼承的類中調用基類的方法?來自:bbs.fishc.com #m.=
c_ZR2o%
答:使用super()這個BIF函數。R`:,~83=v
@%v~ds版權屬於:bbs.fishc.com 4;
  1. class Derived(Base):
  2.     def meth (self):
  3.         super(Derived, self).meth()
複製代碼

l2pcR
3.如果我要繼承的基類是動態的(有時候是A,有時候是B),我應該如何部署我的代碼,以便基類可以隨意改變。@}PxN
=來自:bbs.fishc.com hy}TMqB
答:你可以先為基類定義一個別名,在類定義的時候,使用別名代替你要繼承的基類。如此,當你想要改變基類的時候,只需要修改給別名賦值的那個語句即可。順便說一下,當你的資源是視情況而定的時候,這個小技巧很管用。:7J)mbT
l7yf+tF
舉個例子:'42nyt
  1. BaseAlias = BaseClass # 為基類取別名

  2. class Derived(BaseAlias):
  3.     def meth(self):
  4.         BaseAlias.meth(self) # 通過別名訪問基類
  5.         ...
複製代碼

b"=N!jw
4.嘗試自己舉一個例子說明如何使用類的靜態屬性。(一定要自己先動手再看答案哦^_^)
N)C8Q'^[
答:類的靜態屬性很簡單,在類中直接定義的變量(沒有self.)就是靜態屬性。引用類的靜態屬性使用”類名.屬性名”的形式。er]FO=%WK
"rm{Aq<*>R
類的靜態屬性應用(計算該類被實例化的次數):;vj`qym9b+
  1. class C:
  2.     count = 0 # 靜態屬性

  3.     def __init__(self):
  4.         C.count = C.count + 1 # 類名.屬性名的形式引用

  5.     def getCount(self):
  6.         return C.count
複製代碼

Powered by bbs.fishc.com !{>s1
5.嘗試自己舉例說明如何使用類的靜態方法,並指出使用類的靜態方法有何有點和需要注意的地方?(一定要自己先動手再看答案哦^_^):<pHVd
-T_3(
答:靜態方法是類的特殊方法,靜態方法只需要在普通方法的前邊加上@staticmethod修飾符即可。F9LX: #v;G
vA sT+
  1. class C:
  2.         @staticmethod # 該修飾符表示static() 是靜態方法
  3.         def static(arg1, arg2, arg3):
  4.                 print(arg1, arg2, arg3, arg1 + arg2 + arg3)

  5.         def nostatic(self):
  6.                 print("I'm the f**king normal method!")
複製代碼

靜態方法最大的優點是:不會綁定到實例對像上,換而言之就是節省開銷。;S{:z
  1. >>> c1 = C()
  2. >>> c2 = C()
  3. # 靜態方法只在內存中生成一個,節省開銷
  4. >>> c1.static is C.static
  5. True
  6. >>> c1.nostatic is C.nostatic
  7. False
  8. >>> c1.static
  9. <function C.static at 0x03001420>
  10. >>> c2.static
  11. <function C.static at 0x03001420>
  12. >>> C.static
  13. <function C.static at 0x03001420>
  14. # 普通方法每個實例對像都擁有獨立的一個,開銷較大
  15. >>> c1.nostatic
  16. <bound method C.nostatic of <__main__.C object at 0x03010590>>
  17. >>> c2.nostatic
  18. <bound method C.nostatic of <__main__.C object at 0x032809D0>>
  19. >>> C.nostatic
  20. <function C.nostatic at 0x0328D2B8>
複製代碼

使用的時候需要注意的地方:靜態方法並不需要self參數,因此即使是使用對象去訪問,self參數也不會傳進去。49q:`{
  1. >>> c1.static(1, 2, 3)
  2. 1 2 3 6
  3. >>> C.static(1, 2, 3)
  4. 1 2 3 6
複製代碼

7RpHmX@.%U
E^_l"I-(o
動動手答案:p{]m+"

本帖隱藏的內容

aX(版權屬於:bbs.fishc.com ;W
0.定義一個類,當實例化該類的時候,自動判斷傳入了多少個參數,並顯示出來。z_S9B2qC
UwhfR}8E
答:其實很容易啦,檢查下大家之前的知識點有沒有記牢固而已。Z~k?8
p4.`ON
  1. class C:
  2.         def __init__(self, *args):
  3.                 if not args:
  4.                         print("並沒有傳入參數")
  5.                 else:
  6.                         print("傳入了%d 個參數,分別是:" % len(args), end='')
  7.                         for each in args:
  8.                                 print(each, end=' ')
複製代碼

來自:bbs.fishc.com gX;vI
1.定義一個單詞(Word)類繼承自字符串,重寫比較操作符(參考自學:Python魔法方法詳解),當兩個Word類對象進行比較時,根據單詞的長度來進行比較大小。J1wkp;Kn|+
->~SogAbi,
加分要求:實例化時如果傳入的是帶空格的字符串,則取第一個空格前的單詞作為參數。
Powered by bbs.fishc.com & kuP
9(eJEj0&
答:加分要求可以通過重載__new__方法來實現(因為字符串是不可變類型),通過重寫__gt__、__lt__、__ge__、__le__方法來定義Word類在比較操作中的表現。CQ&Fx<U9X
k8;Kh$J-
注意,我們沒有定義__eq__和__ne__方法。這是因為將會產生一些怪異不符合邏輯的結果(比如Word('FishC' )會等於Word('Apple'))CM|l~)Powered by bbs.fishc.com
}$sPowered by bbs.fishc.com (7來自:bbs.fishc.com
代碼清單:rkd3o9P]7
  1. class Word(str):
  2. '''存儲單詞的類,定義比較單詞的幾種方法'''

  3.     def __new__(cls, word):
  4.         # 注意我們必須要用到__new__ 方法,因為str 是不可變類型
  5.         # 所以我們必須在創建的時候將它初始化
  6.         if ' ' in word:
  7.             print "Value contains spaces. Truncating to first space."
  8.             word = word[:word.index(' ')] #單詞是第一個空格之前的所有字符
  9.         return str.__new__(cls, word)

  10.     def __gt__(self, other):
  11.         return len(self) > len(other)
  12.     def __lt__(self, other):
  13.         return len(self) < len(other)
  14.     def __ge__(self, other):
  15.         return len(self) >= len(other)
  16.     def __le__(self, other):
  17.         return len(self) <= len(other)
複製代碼

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

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

上節課我們介紹了需要關於算術運算的魔法方法,意思是當你的對象進行相關的算術操作的時候,自然而然的就會觸動對應的魔法方法,一旦你重寫了這些魔法方法,那麼Python就會根據你的意圖進行計算。
通過對指定的魔法方法進行重寫,你完全可以讓Python根據你的意圖去實現程序,我們來舉個例子:
我們重寫int 函數,偷偷摸摸的把int 覆蓋掉,重寫之前,它是繼承了正常的int,很明顯,當我們進行加法操作時,給它一個減法操作的結果,然後我們的類還把原來的int 覆蓋掉。
其它方法還是繼承了正常的int,只有加法操作變為了減法。
  1. >>> class int(int):
  2. def __add__(self, other):
  3. return int.__sub__(self,other)
  4. >>> a = int('5')
  5. >>> a
  6. 5
  7. >>> b = int(3)
  8. >>> a + b
  9. 2
  10. >>> a - b
  11. 2
其它內容請自學-> Python魔法方法詳解

0 留言:

發佈留言