## 鴨子型別
「當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就可以被稱為鴨子。」
----
```python
class Cat:
def make_sound(self):
print('Meow~')
class Dog:
def make_sound(self):
print('Woof')
class Bird:
def make_sound(self):
print('♫~♪♫~♪')
zoo = [Cat(), Dog(), Bird()]
for animal in zoo:
animal.make_sound()
```
----
```python=13
class Car:
def make_sound(self):
print('VROOM!')
```
把這台汽車放進動物園裡是完全沒有問題的(程式執行部分)
但我們不會希望去動物園裡觀賞汽車吧
----
鴨子型別**要求編程人員對程式有一定的了解程**
(如果是供人使用的函式庫一定要把文檔寫好)
不然就容易出現範例中的現象
----
所以Python的編程風格並不走完全的鴨子型別
----
定義一個動物類(介面)
```python=
class Animal:
def make_sound():
pass
```
----
```python=5
class Cat(Animal):
def make_sound(self):
print('Meow~')
class Dog(Animal):
def make_sound(self):
print('Woof')
class Bird(Animal):
def make_sound(self):
print('♫~♪♫~♪')
class Car:
def make_sound(self):
print('pu pu')
zoo = [Cat(), Dog(), Bird(), Car()]
for animal in zoo:
if isinstance(animal, Animal): # 檢查物件的超類別
animal.make_sound()
```
---
## 錯誤處理
----
這是一個計算除法的程式
```python=
def division(a, b):
print(f'{a} / {b}')
result = a/b
print(f'= {result}')
return result
division(10, 2)
# 10 / 2
# = 5.0
```
----
當除以0的時候 程式報錯了
```python=7
division(10, 0)
# ZeroDivisionError: division by zero
```
程式也因此停止
----
```python=
def division(a, b):
print(f'{a} / {b}')
try:
result = a/b
except ZeroDivisionError:
print('錯誤! 除數不可為零!')
return None
print(f'= {result}')
return result
division(10,0)
# 10 / 0
# 錯誤! 除數不可為零!
```
當 `try` 內的程式產生錯誤
被 `except` 捕捉
藉由 `return` 讓程式提早結束
----
**except**:
捕捉所有錯誤
**except** `Exception`:
捕捉特定種類(類別)的錯誤
**except** `Exception` **as** `error`:
將錯誤(Exception物件)作為變數
----
```python=7
except ZeroDivisionError:
print('錯誤! 除數不可為零!')
else:
print(f'= {result}')
return result
# 10 / 0
# 錯誤! 除數不可為零!
```
`else` 只有在程式沒有報錯才會執行
(這樣就不用 `return None` 了)
----
```python=
def division(a, b):
print(f'{a} / {b}')
try:
result = a/b # 程式在這裡因為錯誤而中斷
print(f'= {result}')
return result
except ZeroDivisionError:
print('錯誤! 除數不可為零!')
division(10,0)
# 10 / 0
# 錯誤! 除數不可為零!
```
這樣寫看似沒有問題(而且更少行)
但這不是一個好的編程習慣
**try裡面只放可能出現錯誤的程式**
----
```python=
def division(a, b):
print(f'{a} / {b}')
try:
result = a/b
except ZeroDivisionError:
print('錯誤! 除數不可為零!')
else:
print(f'= {result}')
return result
finally:
print('-- 程式結束 --')
division(10,0)
# 10 / 0
# 錯誤! 除數不可為零!
#
# -- 程式結束 --
```
``
----
```python=14
division(10,2)
# 10 / 2
# = 5.0
#
# -- 程式結束 --
```
----
```python=
def division(a, b):
print(f'{a} / {b}')
try:
result = a/b
except ZeroDivisionError:
print('錯誤! 除數不可為零!')
except Exception:
print('錯誤!')
else:
print(f'= {result}')
return result
finally:
print('\n -- 程式結束 --')
division('1','2')
# 1 / 2
# 錯誤!
#
# -- 程式結束 --
```
----
{"metaMigratedAt":"2023-06-16T16:29:21.661Z","metaMigratedFrom":"YAML","title":"Lesson 6","breaks":true,"slideOptions":"{\"transition\":\"fade\",\"parallaxBackgroundImage\":\"https://cdn.discordapp.com/attachments/887196342135451652/889752537513750588/image0.png\",\"parallaxBackgroundSize\":\"2100px 1000px\",\"defaultTiming\":120}","contributors":"[{\"id\":\"35809032-c270-45a6-adab-a7e7a63da25b\",\"add\":3626,\"del\":240}]"}