2020年9月16日星期三

[課後作業] 第040講:類和對象:一些相關的BIF |課後測試題及答案

[課後作業] 第040講:類和對象:一些相關的BIF |課後測試題及答案




《零基礎入門學習Python》視頻下載地址:傳送門,g[B5W?VY
fR,NUz^
測試題:
J Powered by bbs.fishc.com -?^&
0.如何判斷一個類是否為另一個類的子類?!ax%>9
E4sI%1"=c
^zm]iLA
1.如何判斷對象a是否為類A的實例對象?rQ'gPowered by bbs.fishc.com
^來自:bbs.fishc.com fTO%4C,
"rJl*=
2.如何優雅地避免訪問對像不存在的屬性(不產生異常)?ptVv版權屬於:bbs.fishc.com %}EB
cs~3#"
z&bYIHet
3. Python的一些BIF很奇怪,但卻十分有用。請問property()函數的作用是什麼?tZDN_p5vP.
l84Ubm^~
gXT%3KAG
4.請補充以下代碼,使程序可以正常運行:x]T@$^1

!r&jc.

  1. class C:
  2.     def __init__(self, size=10):
  3.         self.size = size

  4.     def getXSize(self):
  5.         return self.size

  6.     def setXSize(self, value):
  7.         self.size = value

  8.     def delXSize(self):
  9.         del self.size

  10.         # 此處應該補充一句代碼,程序才能正常運行

  11. >>> cx
  12. 10
  13. >>> cx = 12
  14. >>> cx
  15. 12
複製代碼

{M6Powered by bbs.fishc.com 1k'L版權屬於:bbs.fishc.com S
5.通過自學【擴展閱讀】Python函數修飾符(裝飾器)的使用,使用修飾符修改以下代碼。[O)amTV-KG
Jh,>#d
代碼A:Vrk]p-UFh
  1. class CodeA:
  2.     def foo():
  3.         print("調用靜態方法foo()")

  4.         # 將foo() 方法設置為靜態方法
  5.         foo = staticmethod(foo)
複製代碼

代碼B:`j版權屬於:bbs.fishc.com ;WF
  1. class CodeB:
  2.     def foo(cls):
  3.         print("調用類方法foo()")

  4.         # 將foo() 方法設置為類方法
  5.         foo = classmethod(foo)
複製代碼

VX*=D8^d>Y
6.你真的理解了修飾符的用法嗎?那請你寫出以下代碼沒有用上修飾符的等同形式:tPowered by bbs.fishc.com hBxW"]`0
  1. @something
  2. def f():
  3.     print("I love FishC.com!")
複製代碼

W _J!+im
7.通過自學【擴展閱讀】property的詳細使用方法,將第4題的代碼修改為“使用屬性修飾符創建描述符”的方式實現。*GqIo
Powered by bbs.fishc.com -+8?
MinfsX
8.請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!aBiNpw



回复您的答案即可查看參考答案!pN!l#U6@
W,`4e
R9UjW4=r^
測試題答案:2-%DX61F<(

本帖隱藏的內容

^.`gI9 e_F
0.如何判斷一個類是否為另一個類的子類?#fSyG:t
ea0B=W
答:使用issubclass(class, classinfo)函數,如果第一個參數(class)是第二個參數(classinfo)的一個子類,則返回True,否則返回False。js5.k
y2Powered by bbs.fishc.com ,<
另外以下這些常識你應該知道:3L4 k[
Y&q^$x}+
  • 一個類被認為是其自身的子類
  • classinfo 可以是類對象組成的元祖,只要class 與其中任何一個候選類的子類,則返回True
  • 在其他情況下,會拋出一個TypeError 異常

y})wa
1.如何判斷對象a是否為類A的實例對象?[|*D版權屬於:bbs.fishc.com xX{
O=(ZIP
答:使用isinstance(object, classinfo)函數,如果第一個參數(object)是第二個參數(classinfo)的實例對象,則返回True,否則返回False。aYX來自:bbs.fishc.com !y_I
QYfE";Md<w
另外以下這些常識你應該知道:cGs1 *
Y來自:bbs.fishc.com ~yPX&,
  • 如果objec t是classinfo 的子類的一個實例,也符合條件
  • 如果第一個參數不是對象,則永遠返回False
  • classinfo 可以是類對象組成的元祖,只要class與其中任何一個候選類的子類,則返回True
  • 如果第二個參數不是類或者由類對象組成的元祖,會拋出一個TypeError 異常

.MNu,{`
2.如何優雅地避免訪問對像不存在的屬性(不產生異常)?#u"x+k
GTB?#b!eZ
答:有兩種方法可以做到。qfy;e4a
r!H xG版權屬於:bbs.fishc.com 7
第一種先使用hasattr(object, name)函數判斷屬性是否存在,如果存在再訪問(第一個參數(object)是對象,第二個參數(name)是屬性名的字符串形式);Q]SyuD
}45!olQPowered by bbs.fishc.com
第二種方法是直接使用getattr(object, name[, default])函數並設置default參數(返回對象指定的屬性值,如果指定的屬性不存在,返回default(可選參數)的值)。y6p^. cEe@
kgPHZ[%_c>
u9nwlM7}
3. Python的一些BIF很奇怪,但卻十分有用。請問property()函數的作用是什麼?L>[YGS06m+
QPowered by bbs.fishc.com $>uh%&nj
答:property()函數允許編程人員輕鬆、有效地管理屬性訪問。scB?J
Moj K%
lRe$nU
4.請補充以下代碼,使程序可以正常運行:Ai,xy
MEGw OaVh)
  1. class C:
  2.     def __init__(self, size=10):
  3.         self.size = size

  4.     def getXSize(self):
  5.         return self.size

  6.     def setXSize(self, value):
  7.         self.size = value

  8.     def delXSize(self):
  9.         del self.size

  10.         # 此處應該補充一句代碼,程序才能正常運行

  11. >>> cx
  12. 10
  13. >>> cx = 12
  14. >>> cx
  15. 12
複製代碼

答:x = property(getXSize, setXSize, delXSize) Gc5^!
@])63|
]{7<oNQi
5.通過自學【擴展閱讀】Python函數修飾符(裝飾器)的使用,使用修飾符修改以下代碼。djK(.{0+&T
b;5+(Bmwl
代碼A:(TKQg_:OJ,
  1. class CodeA:
  2.     def foo():
  3.         print("調用靜態方法foo()")

  4.         # 將foo() 方法設置為靜態方法
  5.         foo = staticmethod(foo)
複製代碼

代碼B:P%34d?|Bc
  1. class CodeB:
  2.     def foo(cls):
  3.         print("調用類方法foo()")

  4.         # 將foo() 方法設置為類方法
  5.         foo = classmethod(foo)
複製代碼

答:其實正是因為設置靜態方法和類方法過於討人吐槽,因此Python的作者才開發出了函數修飾符的形式替代。QV%-UCA
dG,Powered by bbs.fishc.com ^Hb
代碼A:di7y["m
  1. class CodeA:
  2.         @staticmethod
  3.     def foo():
  4.         print("調用靜態方法foo()")
複製代碼

代碼B:- SI?C&].r
  1. class CodeB:
  2.         @classmethod
  3.     def foo(cls):
  4.         print("調用類方法foo()")
複製代碼

a1N@!9]V[.
6.你真的理解了修飾符的用法嗎?那請你寫出以下代碼沒有用上修飾符的等同形式:[dm,PQH5&
  1. @something
  2. def f():
  3.     print("I love FishC.com!")
複製代碼

答:其實Python的修飾符就是一種優雅的封裝,但要注意的是只可以在模塊或類定義內對函數進行修飾,不允許修飾一個類。$Q=BY)+ U
rB+M}^
一個修飾符就是一個函數,它將被修飾的函數做為參數,並返回修飾後的同名函數或其它可調用的東西。Z*taO=;,]H
(O.sn Ry`
  1. @something
  2. def f():
  3.     print("I love FishC.com!")

  4. # 相當於

  5. def f():
  6.     print("I love FishC.com!")

  7. f = something(f)
複製代碼

*0i`,EGy版權屬於:bbs.fishc.com
7.通過自學【擴展閱讀】property的詳細使用方法,將第4題的代碼修改為“使用屬性修飾符創建描述符”的方式實現。Jy?r-_Powered by bbs.fishc.com H
[H;來自:bbs.fishc.com 4 j=3
答:可能你還沒聽說過描述符(這個概念在你學完接下來的幾節課自然會了解),但這一點都影響聰明的你修改這個程序。8w#H1vl@
5H|Iq2i_+
代碼清單:-XFn1
k@ |]%
  1. class C:
  2.     def __init__(self, size=10):
  3.         self.size = size
  4.         
  5.     @property
  6.     def x(self):
  7.         return self.size

  8.     @x.setter
  9.     def x(self, value):
  10.         self.size = value

  11.     @x.deleter
  12.     def x(self):
  13.         del self.size
複製代碼
8.請寫下這一節課你學習到的內容:格式不限,回憶並複述是加強記憶的好方式!

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

今天我們談談和類與對象相關的BIF,也就是內置函數。
(一)issubclass(class, classinfo)
如果第一個參數class 是第二個參數classinfo 的子類,就返回True,關於這個函數有幾點需要注意的:
  1. 一個類被認為是其自身的子類
  2. classinfo 可以是類對象組成的元組,只要class 是其中一個候選類的子類,就返回True
(二)isinstance(object, classinfo)
檢查一個實例對象object 是否屬於一個類classinfo,關於這個函數有幾點需要注意的:
  1. 如果第一個參數不是對象,則永遠返回False
  2. 如果第二個參數不是類或者由類對象組成的元組,則拋出一個TypeError 異常
另外,Python 提供了幾個BIF讓我們訪問對象的屬性:
(三)hasattr(object, name)            attr = attribute:屬性。
測試一個對像是否有指定的屬性。name 要用引號把屬性名引起來。
  1. >>> class C:
  2. def __init__(self, x = 0):
  3. self.x = x
  4. >>> c1 = C()
  5. >>> hasattr(c1, "x")
  6. True
  7. >>> hasattr(c1, x)
  8. Traceback (most recent call last):
  9. File "<pyshell#71>", line 1, in <module>
  10. hasattr(c1, x)
  11. NameError: name 'x' is not defined
(四)getattr(object, name[ , default] )       
返回對象指定的屬性值。如果指定的屬性不存在,如果你有設置default,它會把這個default 參數打印出來,否則會拋出一個AttributeError異常。
  1. >>> class C:
  2. def __init__(self, x = 0):
  3. self.x = x
  4. >>> c1 = C()
  5. >>> getattr(c1, 'x')
  6. 0
  7. >>> getattr(c1, 'y')
  8. Traceback (most recent call last):
  9. File "<pyshell#80>", line 1, in <module>
  10. getattr(c1, 'y')
  11. AttributeError: 'C' object has no attribute 'y'
  12. >>> getattr(c1, 'y', '你所访问的属性不存在')
  13. '你所访问的属性不存在'
(五)setattr(object, name, value)
設定對像中指定屬性的值,如果指定的屬性不存在,會新建一個新的屬性,並給其賦值。
  1. >>> setattr(c1, 'y', '来自江南的你')
  2. >>> getattr(c1, 'y', '你所访问的属性不存在')
  3. '来自江南的你'
(六)delattr(object, name)
刪除對像中指定的屬性,如果屬性不存在,就拋出一個AttributeError異常。
俗話說,條條大路通羅馬。Python 其實提供了好幾個方式供你選擇,property 是一個BIF,作用是通過屬性設置屬性,
property(fget = None, fset = None, fdel = None, doc = None)
property 函數的作用就是設置一個屬性,這個屬性就是去設置定義好的屬性,它的第一個參數fget 是獲取屬性的方法,第一個參數fset 是設置屬性的方法,第一個參數fdel 是刪除屬性的方法。舉例說明:
  1. >>> class C:
  2. def __init__(self, size = 10):
  3. self.size = size
  4. def getSize(self):
  5. return self.size
  6. def setSize(self, value):
  7. self.size = value
  8. def delSize(self):
  9. del self.size
  10. x = property(getSize, setSize, delSize)
  11. >>> c1 = C()
  12. >>> c1.x
  13. 10
  14. >>> c1.getSize()
  15. 10
  16. >>> c1.x = 18
  17. >>> c1.getSize()
  18. 18
  19. >>> c1.setSize(20)
  20. >>> c1.x
  21. 20
  22. >>> del c1.x
  23. >>> c1.getSize()
  24. Traceback (most recent call last):
  25. File "<pyshell#104>", line 1, in <module>
  26. c1.getSize()
  27. File "<pyshell#94>", line 5, in getSize
  28. return self.size
  29. AttributeError: 'C' object has no attribute 'size'
property 的優勢:舉個例子,在上面這個例子中,這個程序慢慢寫的很複雜了,有一天,你想把這個程序進行大改,把函數名進行改寫,如果沒有property,那你提供給用戶的調用接口就西藥修改,就會降低用戶體驗,但是有了property,問題就不存在了,因為提供給用戶的接口都是x,程序裡面無論如何修改,property裡面的參數跟著改進行了,用戶還是只用調用x 來設置或者獲取size 屬性就可以了。

0 留言:

發佈留言