內(nèi)容來源于網(wǎng)絡(luò),本人只是在此稍作整理哪替,如有涉及版權(quán)問題栋荸,歸小甲魚官方所有。
練習(xí)題(來自小甲魚官方論壇)
0.什么是組合(組成)?
答:Python繼承機制很有用晌块,但容易把代碼復(fù)雜化以及依賴隱含繼承爱沟。因此,經(jīng)常的時候匆背,我們可以使用組合來代替呼伸。在Python里組合其實很簡單,直接在類定義中把需要的類放進去實例化就可以了钝尸。
舉個例子:
# 烏龜類
class Turtle:
def __init__(self, x):
self.num = x
# 魚類
class Fish:
def __init__(self, x):
self.num = x
# 水池類
class Pool:
def __init__(self, x, y):
self.turtle = Turtle(x) # 把烏龜類實例化組合進來
self.fish = Fish(y) # 把魚類實例化組合進來
def print_num(self):
print("水池里總共有烏龜 %d 只括享,小魚 %d 條!" % (self.turtle.num, self.fish.num))
pool = Pool(1, 10)
pool.print_num()
1.什么時候用組合蝶怔,什么時候用繼承奶浦?
答:根據(jù)實際應(yīng)用場景確定。簡單的說踢星,組合用于“有一個”場景中澳叉,繼承用于“是一個”場景中。例如沐悦,水池里有一個烏龜成洗,天上有一只鳥,地上有一個小甲魚藏否,這些適合使用組合瓶殃。絲瓜是瓜,女人是人副签,鯊魚是魚遥椿,這些就應(yīng)該使用繼承。
2.類對象是在什么時候產(chǎn)生淆储?
答:當(dāng)你這個類定義完的時候冠场,類定義就變成類對象,可以直接通過“類名.屬性”或者“類名.方法名()”引用或使用相關(guān)的屬性或方法本砰。
3.如果對象的屬性跟方法名字相同碴裙,會怎樣?
答:如果對象的屬性跟方法名相同点额,屬性會覆蓋方法舔株。
舉個例子:
>>> class C:
def x(self):
print("Xman")
>>> c = C()
>>> c.x()
Xman
>>> c.x = 111 # 定義x屬性
>>> c.x
111
>>> c.x() # 方法已經(jīng)被覆蓋掉了,所以調(diào)用報錯了
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
c.x()
TypeError: 'int' object is not callable
4.請問以下類定義中哪些是類屬性还棱,哪些是實例屬性?
class C:
num = 0
def __init__(self):
self.x = 4
self.y = 5
C.count = 6
答:num和count是類屬性(靜態(tài)變量)载慈,x和y是實例屬性。大多數(shù)情況下珍手,你應(yīng)該考慮使用實例屬性娃肿,而不是類屬性(類屬性通常僅用來跟蹤與類相關(guān)的值)咕缎。
5.請問以下代碼中,bb對象為什么調(diào)用printBB()方法失效料扰?
>>> class BB:
def printBB():
print("no zuo no die")
>>> bb = BB()
>>> bb.printBB()
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
bb.printBB()
TypeError: printBB() takes 0 positional arguments but 1 was given
答:因為Python嚴(yán)格要求方法需要有實例才能被調(diào)用凭豪,這種限制其實就是Python所謂的綁定概念。所以Python會自動把bb對象作為第一個參數(shù)傳入晒杈,即bb.printBB(bb)嫂伞,然而類方法那邊沒有參數(shù),所以才會出現(xiàn)TypeError:“需要0個參數(shù)拯钻,但實際傳入了1個參數(shù)”帖努。
正確的做法應(yīng)該是:
>>> class BB:
def printBB(self):
print("no zuo no die")
>>> bb = BB()
>>> bb.printBB()
no zuo no die
編程題
0.思考這一講學(xué)習(xí)的內(nèi)容,請動手在一個類中定義一個變量粪般,用于跟蹤類有多少個實例被創(chuàng)建(當(dāng)實例化一個對象拼余,這個變量+1,當(dāng)銷毀一個對象亩歹,這個變量自動-1)匙监。
>>> class C:
count = 0
def __init__(self):
C.count += 1
def __del__(self):
C.count -= 1
>>> a = C()
>>> b = C()
>>> c = C()
>>> C.count
3
>>> del a
>>> C.count
2
>>> del b,c
>>> C.count
0
1.定義一個棧(Stack)類,用于模擬一種具有后進先出(LIFO)特征的數(shù)據(jù)結(jié)構(gòu)小作。至少需要有以下辦法:
方法名 | 含義 |
---|---|
isEmpty() | 判斷當(dāng)前棧是否為空(返回True或False) |
push() | 往棧的頂部壓入一個數(shù)據(jù)項 |
pop() | 從棧頂彈出一個數(shù)據(jù)項(并在棧中刪除) |
top() | 顯示當(dāng)前棧頂?shù)囊粋€數(shù)據(jù)項 |
botton() | 顯示當(dāng)前棧底的一個數(shù)據(jù)項 |
答:代碼如下:
class Stack():
def __init__(self, start=[]):
self.stack = []
for x in start:
self.push(x)
def isEmpty(self): # 判斷是否為空
return not self.stack
def push(self, obj): # 入棧
print("成功入棧數(shù)據(jù):", obj)
self.stack.append(obj)
def pop(self): # 出棧
if not self.stack:
print("警告:棧為空亭姥!")
else:
print("成功出棧數(shù)據(jù):", self.stack[-1])
return self.stack.pop()
def top(self): # 顯示第一個棧頂數(shù)據(jù)
if not self.stack:
print("警告:棧為空!")
else:
print("棧頂數(shù)據(jù)為:", end="")
return self.stack[-1]
def bottom(self): # 顯示棧底數(shù)據(jù)
if not self.stack:
print("警告:棧為空顾稀!")
else:
print("棧底數(shù)據(jù)為:", end="")
return self.stack[0]
def showStack(self): # 展示棧內(nèi)的所有數(shù)據(jù)(自己附加上去的方法达罗,為了方便看棧內(nèi)還有哪些數(shù)據(jù))
print("目前棧內(nèi)的所有數(shù)據(jù)為:", end="")
return self.stack[:]
s = Stack([])
print(s.isEmpty()) # True
s.push('1')
s.push('2')
s.push('3')
s.push('4')
s.push('5')
print(s.showStack())
print(s.top()) # 棧頂是5
s.pop() # 5被彈出,棧頂變成4
print(s.showStack())
print(s.top())
print(s.bottom())
輸出:
True
成功入棧數(shù)據(jù): 1
成功入棧數(shù)據(jù): 2
成功入棧數(shù)據(jù): 3
成功入棧數(shù)據(jù): 4
成功入棧數(shù)據(jù): 5
目前棧內(nèi)的所有數(shù)據(jù)為:['1', '2', '3', '4', '5']
棧頂數(shù)據(jù)為:5
成功出棧數(shù)據(jù): 5
目前棧內(nèi)的所有數(shù)據(jù)為:['1', '2', '3', '4']
棧頂數(shù)據(jù)為:4
棧底數(shù)據(jù)為:1
2.請寫下這一節(jié)課你學(xué)習(xí)到的內(nèi)容:格式不限静秆,回憶并復(fù)述是加強記憶的好方式粮揉!
- 組合
- 類、類對象和實例對象
- 綁定