Python 程式設計入門 - 09

Pyladies Taiwan

Speaker : Mars

2018/02/04

Roadmap

  • 異常
  • 異常處理
  • while、break、continue
  • 補充知識-引發異常

異常 exception

當發生異常的時候,程式會中斷無法繼續執行

內建的異常型別

在Python中,所有東西都是物件,「異常」當然也是!
所以異常也是有各自的型別,也會有「繼承」關係。

In [1]:
print(123
  File "<ipython-input-1-42accc500add>", line 1
    print(123
             ^
SyntaxError: unexpected EOF while parsing
In [2]:
print(SyntaxError)
<class 'SyntaxError'>
In [3]:
print("Hi")
 print(123)
  File "<ipython-input-3-2a06b128fde9>", line 2
    print(123)
    ^
IndentationError: unexpected indent
In [4]:
for i in range(3):
print(i)
  File "<ipython-input-4-e9b0282dd71e>", line 2
    print(i)
        ^
IndentationError: expected an indented block
In [5]:
for i in range(3):
    print(i)
   print("i",i)
  File "<ipython-input-5-a41a15e092f4>", line 3
    print("i",i)
                ^
IndentationError: unindent does not match any outer indentation level
In [6]:
print(name)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-6-7fa07326b3c2> in <module>()
----> 1 print(name)

NameError: name 'name' is not defined
In [7]:
print(3/0)
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-7-9f9f9b129daa> in <module>()
----> 1 print(3/0)

ZeroDivisionError: division by zero
In [8]:
print(int("Hi"))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-85fe01792a10> in <module>()
----> 1 print(int("Hi"))

ValueError: invalid literal for int() with base 10: 'Hi'
In [9]:
print("Hi"+123)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-d949a9827c8e> in <module>()
----> 1 print("Hi"+123)

TypeError: Can't convert 'int' object to str implicitly
In [10]:
l = []
print(l[0])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-10-489312ee7a09> in <module>()
      1 l = []
----> 2 print(l[0])

IndexError: list index out of range
In [11]:
d = {}
print(d["key"])
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-11-26b181a88f96> in <module>()
      1 d = {}
----> 2 print(d["key"])

KeyError: 'key'

目前我們學的語法,可以怎麼避免掉這些異常呢?

d = {}
print(d["key"])
print(d["other_key"])
In [12]:
d = {}
print(d.get("key","nothing"))
print(d.get("other_key","nothing"))
nothing
nothing
In [13]:
if "key" in d:
    print(d["key"])
else:
    print("nothing")
if "other_key" in d:
    print(d["other_key"])
else:
    print("nothing")
nothing
nothing

用函式的寫法

In [14]:
def get(d,key):
    if key in d:
        return d[key]
    else:
        return "nothing"
d = {}
print(get(d,"key"))
print(get(d,"other_key"))
nothing
nothing

print改放在函式裡

In [15]:
def my_print(d,key):
    if key in d:
        print(d[key])
    else:
        print("nothing")
d = {}
my_print(d,"key")
my_print(d,"other_key")
nothing
nothing

還有其他的資料型別同時存在...

d = {}
l = []
print(d["key"])
print(l[0])
print(d["other_key"])
In [16]:
def my_print(data,ik):
    if isinstance(data,list):
        if ik in range(0,len(data)):
            print(data[ik])
        else:
            print("nothing")
    if isinstance(data,dict):
        if ik in data:
            print(data[ik])
        else:
            print("nothing")
d = {}
l = []
my_print(d,"key")
my_print(l,0)
my_print(d,"other_key")
nothing
nothing
nothing

異常處理

try:
    可能會發生異常的程式碼

except:
    發生任何異常要執行的程式碼

except 異常型別名:
    發生異常型別要執行的程式碼
except 異常型別名 as 名稱:
    發生異常型別要執行的程式碼,且為此異常物件取名稱

except (異常型別名1,異常型別名2,....):
    發生異常型別1,2,....要執行的程式碼
except (異常型別名1,異常型別名2,....) as 名稱:
    發生異常型別1,2,....要執行的程式碼,且為此異常物件取名稱

else:
    未發生異常時要執行的程式碼
finally:
    不論如何都會執行的程式碼

注意:

  • except, finally 至少要有一存在
  • except 有多種寫法
  • else 可有可無
  • 直接用except雖然很方便,但因為沒有綁定名稱,會讓你找不到bug所在
d = {}
l = []
print(d["key"])
print(l[0])
print(d["other_key"])
In [17]:
def my_print(data,ik):
    try:
        print(data[ik])
    except:
        print("nothing")
        
d = {}
l = []
a = 1234
my_print(d,"key")
my_print(l,0)
my_print(d,"other_key")
my_print(a,1)
nothing
nothing
nothing
nothing
In [18]:
def my_print(data,ik):
    try:
        print(data[ik])
    except (KeyError,IndexError):
        print("nothing")
    except:
        print("資料型別錯誤")
        
d = {}
l = []
a = 1234
my_print(d,"key")
my_print(l,0)
my_print(d,"other_key")
my_print(a,1)
nothing
nothing
nothing
資料型別錯誤
user_input = input("請輸入欲計算的除法內容")
try:
    a,b = user_input.split("/")
    print("a={}, b={}".format(a,b))
    a = eval(a) # 可直接把字串當成運算式執行
    b = int(b)
    print("a={}, b={}".format(a,b))
    print(a/b)
except ZeroDivisionError:
    print("分母為0,無法計算")
except ValueError as e:
    print("計算錯誤:{}".format(e))
except:
    print("計算錯誤")
else:
    print("計算成功")
finally:
    print("程式結束")

以下輸入會有各種結果

  • 5+3/2 => 8/2 = 4.0
  • 5/0 => ZeroDivisionError
  • 5/Hi => ValueError
  • 5 => ValueError
  • 5+3)/2 => SyntaxError

在異常狀況不做任何處理 pass

  • pass就只是為了符合Python句法結構,實際上什麼事都不會做。
In [19]:
try:
    output = 5/0
except:
    pass
finally:
    print("結束")
結束

異常名稱的範圍

except 指派的名稱只會存在自己的範圍裡

In [20]:
try:
    output = 5/0
except ZeroDivisionError as e:
    print(e)
finally:
    print(e)
division by zero
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-20-28fd11fd0c5b> in <module>()
      4     print(e)
      5 finally:
----> 6     print(e)

NameError: name 'e' is not defined
In [21]:
error = None
try:
    output = 5/0
except ZeroDivisionError as e:
    error = e
    print(e)
finally:
    print(error)
division by zero
division by zero

finally 和 return

一般的函式都是以最先的執行的retun為回傳值,
但當使用了異常處理,try與finally都有return時,會以finally的return為回傳值。

In [22]:
def f():
    return "try"
    return "finally"
    return "f"
print(f())
try
In [23]:
def f():
    try:
        return "try"
    finally:
        return "finally"
    return "f"
print(f())
finally

實務上會遇到的狀況-以網路爬蟲為例

  • 可能網址不存在 => 404 Not Found
  • 可能整個網站掛了 => ERR_CONNECTION_TIMED_OUT
In [24]:
import requests
from lxml import etree
resp = requests.get("http://www.slime.com.tw/tutorial/os.htm")
html = resp.text
page = etree.HTML(html)
url_set = set(page.xpath("//a[contains(@href,'http')]/@href"))
for url in url_set:
    if "www.slime.com.tw" not in url:
        print(url)
        resp = requests.get(url, timeout=0.5)
        resp.raise_for_status() # 如果有發生404等錯誤請求,引發異常
        html = resp.text
http://netlab.cse.yzu.edu.tw/~statue/freebsd/docs/aasir/
---------------------------------------------------------------------------
timeout                                   Traceback (most recent call last)
/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connection.py in _new_conn(self)
    140             conn = connection.create_connection(
--> 141                 (self.host, self.port), self.timeout, **extra_kw)
    142 

/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/util/connection.py in create_connection(address, timeout, source_address, socket_options)
     82     if err is not None:
---> 83         raise err
     84 

/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/util/connection.py in create_connection(address, timeout, source_address, socket_options)
     72                 sock.bind(source_address)
---> 73             sock.connect(sa)
     74             return sock

timeout: timed out

During handling of the above exception, another exception occurred:

ConnectTimeoutError                       Traceback (most recent call last)
/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
    599                                                   body=body, headers=headers,
--> 600                                                   chunked=chunked)
    601 

/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py in _make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
    355         else:
--> 356             conn.request(method, url, **httplib_request_kw)
    357 

/usr/lib/python3.4/http/client.py in request(self, method, url, body, headers)
   1087         """Send a complete request to the server."""
-> 1088         self._send_request(method, url, body, headers)
   1089 

/usr/lib/python3.4/http/client.py in _send_request(self, method, url, body, headers)
   1125             body = body.encode('iso-8859-1')
-> 1126         self.endheaders(body)
   1127 

/usr/lib/python3.4/http/client.py in endheaders(self, message_body)
   1083             raise CannotSendHeader()
-> 1084         self._send_output(message_body)
   1085 

/usr/lib/python3.4/http/client.py in _send_output(self, message_body)
    921             message_body = None
--> 922         self.send(msg)
    923         if message_body is not None:

/usr/lib/python3.4/http/client.py in send(self, data)
    856             if self.auto_open:
--> 857                 self.connect()
    858             else:

/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connection.py in connect(self)
    165     def connect(self):
--> 166         conn = self._new_conn()
    167         self._prepare_conn(conn)

/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connection.py in _new_conn(self)
    145                 self, "Connection to %s timed out. (connect timeout=%s)" %
--> 146                 (self.host, self.timeout))
    147 

ConnectTimeoutError: (<requests.packages.urllib3.connection.HTTPConnection object at 0x7fdf525bd8d0>, 'Connection to netlab.cse.yzu.edu.tw timed out. (connect timeout=0.5)')

During handling of the above exception, another exception occurred:

MaxRetryError                             Traceback (most recent call last)
/usr/local/lib/python3.4/dist-packages/requests/adapters.py in send(self, request, stream, timeout, verify, cert, proxies)
    422                     retries=self.max_retries,
--> 423                     timeout=timeout
    424                 )

/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/connectionpool.py in urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
    648             retries = retries.increment(method, url, error=e, _pool=self,
--> 649                                         _stacktrace=sys.exc_info()[2])
    650             retries.sleep()

/usr/local/lib/python3.4/dist-packages/requests/packages/urllib3/util/retry.py in increment(self, method, url, response, error, _pool, _stacktrace)
    375         if new_retry.is_exhausted():
--> 376             raise MaxRetryError(_pool, url, error or ResponseError(cause))
    377 

MaxRetryError: HTTPConnectionPool(host='netlab.cse.yzu.edu.tw', port=80): Max retries exceeded with url: /~statue/freebsd/docs/aasir/ (Caused by ConnectTimeoutError(<requests.packages.urllib3.connection.HTTPConnection object at 0x7fdf525bd8d0>, 'Connection to netlab.cse.yzu.edu.tw timed out. (connect timeout=0.5)'))

During handling of the above exception, another exception occurred:

ConnectTimeout                            Traceback (most recent call last)
<ipython-input-24-c379a8ffc3a6> in <module>()
      8     if "www.slime.com.tw" not in url:
      9         print(url)
---> 10         resp = requests.get(url, timeout=0.5)
     11         resp.raise_for_status() # 如果有發生404等錯誤請求,引發異常
     12         html = resp.text

/usr/local/lib/python3.4/dist-packages/requests/api.py in get(url, params, **kwargs)
     68 
     69     kwargs.setdefault('allow_redirects', True)
---> 70     return request('get', url, params=params, **kwargs)
     71 
     72 

/usr/local/lib/python3.4/dist-packages/requests/api.py in request(method, url, **kwargs)
     54     # cases, and look like a memory leak in others.
     55     with sessions.Session() as session:
---> 56         return session.request(method=method, url=url, **kwargs)
     57 
     58 

/usr/local/lib/python3.4/dist-packages/requests/sessions.py in request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    486         }
    487         send_kwargs.update(settings)
--> 488         resp = self.send(prep, **send_kwargs)
    489 
    490         return resp

/usr/local/lib/python3.4/dist-packages/requests/sessions.py in send(self, request, **kwargs)
    607 
    608         # Send the request
--> 609         r = adapter.send(request, **kwargs)
    610 
    611         # Total elapsed time of the request (approximately)

/usr/local/lib/python3.4/dist-packages/requests/adapters.py in send(self, request, stream, timeout, verify, cert, proxies)
    477                 # TODO: Remove this in 3.0.0: see #2811
    478                 if not isinstance(e.reason, NewConnectionError):
--> 479                     raise ConnectTimeout(e, request=request)
    480 
    481             if isinstance(e.reason, ResponseError):

ConnectTimeout: HTTPConnectionPool(host='netlab.cse.yzu.edu.tw', port=80): Max retries exceeded with url: /~statue/freebsd/docs/aasir/ (Caused by ConnectTimeoutError(<requests.packages.urllib3.connection.HTTPConnection object at 0x7fdf525bd8d0>, 'Connection to netlab.cse.yzu.edu.tw timed out. (connect timeout=0.5)'))
In [25]:
import requests
from lxml import etree
resp = requests.get("http://www.slime.com.tw/tutorial/os.htm")
html = resp.text
page = etree.HTML(html)
url_set = set(page.xpath("//a[contains(@href,'http')]/@href"))
for url in url_set:
    if "www.slime.com.tw" not in url:
        print(url)
        try:
            resp = requests.get(url, timeout=2)
            resp.raise_for_status()
        except Exception as e:
            print(e)
        else:
            html = resp.text
http://netlab.cse.yzu.edu.tw/~statue/freebsd/docs/aasir/
HTTPConnectionPool(host='netlab.cse.yzu.edu.tw', port=80): Max retries exceeded with url: /~statue/freebsd/docs/aasir/ (Caused by ConnectTimeoutError(<requests.packages.urllib3.connection.HTTPConnection object at 0x7fdf525a9e10>, 'Connection to netlab.cse.yzu.edu.tw timed out. (connect timeout=2)'))
http://www.aasir.com/
HTTPSConnectionPool(host='www.hugedomains.com', port=443): Read timed out. (read timeout=2)
http://lovezutto.googlepages.com/minix3-setup-trad-chinese.html
http://girvan.blogspot.com/
http://lovezutto.googlepages.com/minix3-faq-trad-chinese.html
http://ftp.ncnu.edu.tw/Documentation/Linux/Mandrake_eBook/
404 Client Error: Not Found for url: http://ftp.ncnu.edu.tw/Documentation/Linux/Mandrake_eBook/
http://www.mota.com.tw/Web/pub/LatestItem.aspx?parent=-7&folder=11750
HTTPConnectionPool(host='www.mota.com.tw', port=80): Max retries exceeded with url: /Web/pub/LatestItem.aspx?parent=-7&folder=11750 (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x7fdf51adc8d0>: Failed to establish a new connection: [Errno -2] Name or service not known',))
http://www.scu.edu.tw/cc/newsletter/91-06/winxp.htm
404 Client Error: Not Found for url: http://www.scu.edu.tw/cc/newsletter/91-06/winxp.htm
http://girvanclass.blogspot.com/2007/06/blog-post.html
404 Client Error: Not Found for url: http://girvanclass.blogspot.jp/2007/06/blog-post.html
http://ftp.ncnu.edu.tw/Documentation/Linux/RedHat_Fedora_eBook/
404 Client Error: Not Found for url: http://ftp.ncnu.edu.tw/Documentation/Linux/RedHat_Fedora_eBook/
http://inote.tw/2008/11/wine.html
http://paching.myweb.hinet.net/
http://ftp.ncnu.edu.tw/Documentation/Linux/RedHat_Fedora_set_site/
404 Client Error: Not Found for url: http://ftp.ncnu.edu.tw/Documentation/Linux/RedHat_Fedora_set_site/

練習-檔案異常處理

之前在做檔案處理時,
如果輸出的檔案是在某個資料夾底下,但該資料夾卻不存在,會引發異常,
請用try/except處理:若資料夾不存在,印出「資料夾不存在」。

  • 建議使用 except 異常型別名: 的寫法
    • 可以先看看資料夾不存在是產生怎樣的錯誤

可能會有這兩種寫法,試試看try/except應該放在哪裡
當然直接包最外層也是可以(超級懶惰xD),但不是最好的寫法=D

Type 1

fo = open("tmp/test.txt","w")
fo.write("data")
fo.close()

Type 2

with open("tmp/test.txt","w") as fo:
    fo.write("444")

進階:

下列程式碼可以在path路徑下建立資料夾

import os
os.mkdir(path)
  • path為字串
  • 只能建立一層資料夾

while、break、continue

while

if 條件成立(True):
    要做的事
    要做的事

while 條件成立(True):
    重複要做的事
    重複要做的事

for 名稱 in 可迭代的資料型別:
    重複要做的事
    重複要做的事
  • for
    • 處理「已知」次數的重複狀況
    • 常用在取出元素
  • while
    • 處理「未知」次數的重複狀況
In [26]:
# 發5張牌(撲克牌每一張都是完全不同的牌面)
import random
number_list = ["A","J","Q","K"]
for i in range(1,10+1):
    number_list.append(str(i))
color_list = ["黑桃","梅花","紅心","方塊"]

my_card = []
while(len(my_card)<5):
    card = random.choice(color_list)+random.choice(number_list)
    if card not in my_card:
        my_card.append(card)
    print (card)
紅心10
方塊4
黑桃5
黑桃2
黑桃7

while "I am satisfied with my care" not in word:
    make_happy()
while hp>0:
    fighting()
print("You are dead")

today_count = 0
while is_in_opentime(now_time):
    if is_someone_comin:
        today_count += 1
print(today_count)
In [27]:
import random
with open("choice.txt") as fi:
    data = fi.read()
food_list = data.split("\n")
print(random.choice(food_list))
7-11
import random
food_list = ["牛肉麵","麥當勞","7-11"]

def get_suggestion():
    return random.choice(food_list)

while True:
    user_input = input()
    if "謝謝" in user_input:
        print("祝你有個愉快的一餐")
    elif ("好餓喔" in user_input) or ("換一個" in user_input):
        print(get_suggestion())
    else:
        print("我聽不懂你在說什麼")

print("程式結束")

break

跳出最近的迴圈(for、while)

import random
food_list = ["牛肉麵","麥當勞","7-11"]

def get_suggestion():
    return random.choice(food_list)

while True:
    user_input = input()
    if "謝謝" in user_input:
        print("祝你有個愉快的一餐")
        break ###
    elif ("好餓喔" in user_input) or ("換一個" in user_input):
        print(get_suggestion())
    else:
        print("我聽不懂你在說什麼")

print("程式結束")
In [28]:
# dresscode要全部的人都穿藍色衣服才能進場
people = ["blue","black","blue","blue","blue"]
for color in people:
    print("now color =",color)
    if color !="blue":
        break
now color = blue
now color = black
In [29]:
# dresscode要全部的人都穿藍色衣服才能進場(雙重迴圈)
people = [["blue","blue"],["black","blue","blue"],["blue"]]
for group in people:
    print("now_group =",group)
    for color in group:
        print("    now color =",color)
        if color !="blue":
            break
now_group = ['blue', 'blue']
    now color = blue
    now color = blue
now_group = ['black', 'blue', 'blue']
    now color = black
now_group = ['blue']
    now color = blue

continue

繼續最近的迴圈(for、while)

In [30]:
# 單價<10的物品不進貨
item_list = [("orange",20),("lemon",5),("banana",15),("apple",25)]
stock = []
for item in item_list:
    if item[1]<10:
        continue
    stock.append(item)
print(stock)
[('orange', 20), ('banana', 15), ('apple', 25)]
In [31]:
# 程式當然不只一種寫法
item_list = [("orange",20),("lemon",5),("banana",15),("apple",25)]
stock = []
for item in item_list:
    if item[1]>10:
        stock.append(item)
print(stock)
[('orange', 20), ('banana', 15), ('apple', 25)]

練習-猜數字遊戲

  • 程式生成一個1~100的隨機數 (random傳送門)
  • 讓使用者能輸入猜的數字,提示字為「請輸入你想要猜的數字」(input傳送門)
  • 輸入的字串轉成數字,或是將生成的隨機數轉成字串 (型別轉換傳送門)
  • 判斷對錯
    • 猜對,印出「猜對了」
    • 猜錯,判斷大小,印出「比這個數字更大/更小」

Think:

  • 哪些步驟會重複做
  • 遊戲什麼時候結束(程式中斷點)

Hint:

# 程式生成一個1~100的隨機數
import random
program_number = random.randrange(1, 100)
print("偷看答案",program_number)

# 讓使用者能輸入猜的數字,提示字為「請輸入你想要猜的數字
user_input = input("請輸入你想要猜的數字")

# 輸入的字串轉成數字
user_number = int(user_input)

# 判斷對錯
if program_number == user_number:
    print("猜對了")
else:
    if program_number>user_number:
        print("比這個數字更大")
    else:
        print("比這個數字更小")

補充知識-引發異常

raise

raise
raise 異常物件
raise 異常型別名

注意:

  • 如果只有raise,會再次引發當前活動中的異常,
    如果當前活動中無異常,會引發RuntimeError
In [32]:
a = 5
if a==5:
    print("fine")
else:
    raise
fine
In [33]:
a = 10
if a==5:
    print("fine")
else:
    raise # 當前無任何異常 => RuntimeError
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-33-01b39371d75f> in <module>()
      3     print("fine")
      4 else:
----> 5     raise # 當前無任何異常 => RuntimeError

RuntimeError: No active exception to reraise
In [34]:
a = 10
if a==5:
    print("fine")
else:
    raise ValueError
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-34-58359e623f34> in <module>()
      3     print("fine")
      4 else:
----> 5     raise ValueError

ValueError: 

再次引發異常

In [35]:
try:
    output = 5/0
except ZeroDivisionError as e:
    print("分母不得為0")
分母不得為0
In [36]:
try:
    output = 5/0
except ZeroDivisionError as e:
    print("分母不得為0")
    raise # 當前異常為ZeroDivisionError
分母不得為0
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-36-64f5da622ae1> in <module>()
      1 try:
----> 2     output = 5/0
      3 except ZeroDivisionError as e:
      4     print("分母不得為0")
      5     raise # 當前異常為ZeroDivisionError

ZeroDivisionError: division by zero

建立新的錯誤訊息-保留原本訊息

raise 異常型別名/異常物件(訊息) from 名稱
In [37]:
try:
    output = 5/0
except ZeroDivisionError as e:
    s = "分母不得為0"
    raise ZeroDivisionError(s) from e
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-37-42c30026ec5e> in <module>()
      1 try:
----> 2     output = 5/0
      3 except ZeroDivisionError as e:

ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-37-42c30026ec5e> in <module>()
      3 except ZeroDivisionError as e:
      4     s = "分母不得為0"
----> 5     raise ZeroDivisionError(s) from e

ZeroDivisionError: 分母不得為0

建立新的錯誤訊息-捨棄原本訊息

raise 異常型別名/異常物件(訊息) from None
In [38]:
try:
    output = 5/0
except ZeroDivisionError as e:
    s = "分母不得為0"
    raise ZeroDivisionError(s) from None
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-38-b2db6a720dba> in <module>()
      3 except ZeroDivisionError as e:
      4     s = "分母不得為0"
----> 5     raise ZeroDivisionError(s) from None

ZeroDivisionError: 分母不得為0

assert:只會引發Assertion Error異常

assert 運算式
assert 運算式,出錯原因
In [39]:
assert 5+5==10,"First"
assert 5<10,"Second"
print('Done. Time to Check.')
Done. Time to Check.
In [40]:
assert 5+5==10,"First"
assert 5>10,"Second"
print('Done. Time to Check.')
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-40-9bf0e99a1e5a> in <module>()
      1 assert 5+5==10,"First"
----> 2 assert 5>10,"Second"
      3 print('Done. Time to Check.')

AssertionError: Second

學習資源對應

書中講過的內容

  • 物件、型別轉換:int(字串)、str(數字)
  • 字串:split,strip,replace,isalpha,lower
  • 串列:append
  • 序列共同介面:index,count,len,切片
  • 字典、集合
  • 判斷式、in
  • 迴圈
  • 檔案
  • 函式,排序
  • 好用模組
  • 異常

書中沒講到的內容

  • 06 函式:遞迴、高階函式、產生器 generator
  • 08 其他容器型別
  • 09 再談函式:再談遞迴、裝飾器 decorator、函數式程式設計
  • 10 物件導向程式設計 OOP:類別class、繼承、多重繼承、後設類別
  • 13 延伸學習:程式撰寫風格和實務作法、命令列參數、圖形介面、並行處理

Python 各種領域的程式庫/框架

  • [檔案處理與路徑]:os、shutil、sys
  • [網路爬蟲]:urllib、requests、lxml、beautiful_soup、scrapy、selenium
  • [資料庫串接]:sqlite3(sqlite)、MySQLdb(MySQL)、pymssql(MSSQL)、Psycopg(PostgreSQL)
  • [自然語言]:NLTK、jieba
  • [統計應用]:pandas、numpy、scipy、matplotlib
  • [機器學習]:scikit-learn、TensorFlow
  • [影像處理]:PIL、opencv
  • [網站架設]:Django、Flask
  • [網路分析]:scapy、socket
  • [GUI設計]:tkinter、PyQt
  • [軟硬整合]:raspberry pi 樹莓派、Arduino、puSerial
  • [遊戲開發]:pygame
  • [App開發]:kivy
  • [各種服務的API串接]:Bot