(十四)python 包的相對匯入,異常,try,raise語句,assert語句
目錄
__init__.py內的__all__列表
作用:
用來記錄此包中有哪些包或模組需要在from import *語句匯入時被匯入
說明:
__all__列表只在from xxx import * 語句中起作用
包的相對匯入
是指包內模組的相互匯入
語法:
from 相對路徑包或模組import * 屬性或模組
或
from 相對路徑包或模組import *
說明:
包的相對匯入不能用於import xxx語句中
相對路徑:
. 代表當前路徑
.. 代表上一級目錄
... 代表上二級目錄
.... 以此類推
注:相對匯入時不能超出包的外部
包的載入路徑:
同模組的載入路徑搜尋
1.搜尋當前路徑
2.搜尋sys.path給定的路徑
異常(基礎)exception
什麼是錯誤
錯誤是指由於邏輯或語法等導致一個程式無法正常執行的問題
特點:
有些錯誤是無法預知的
什麼是異常
異常是程式出錯時標識的一種狀態
當異常發生時,程式不會再向下執行,
而轉去呼叫此函式的地方待處理此錯誤並恢復為正常狀態
作用:
用作訊號,通知上層呼叫者有錯誤需要處理
try語句
兩種語法:
try-except 語句
try-finally語句
try-except 語句語法
try: 可能觸發異常的語句 except 錯誤型別1 [as 變數1]: 異常處理語句1 except 錯誤型別2 [as 變數2]: 異常處理語句2 except (錯誤型別3,錯誤型別4) [as 變數3]: 異常處理語句3 ... except: 異常處理語句other else: 未發生異常語句 finally: 最終語句
作用:
嘗試捕獲異常,將程式轉為正常狀態並繼續執行
# 此示例示意 try-except語句的用法
def div_apple(n):
print("%d個蘋果您想分給幾個人?" % n)
s = input("請輸入人數: ")
cnt = int(s) # <--此處可能觸發ValueError型別的錯誤
result = n / cnt # <-- 此處可能會觸發ZeroDivisionError型別的錯誤
print("每個人分了%d個蘋果" % result)
try:
div_apple(10) # 此函式可能會觸發錯誤,分蘋果失敗
print("分完蘋果")
except ValueError:
print("分蘋果失敗,程式已捕獲通知並轉為正常狀態")
except ZeroDivisionError:
print("沒有人來,那蘋果就拿來回吧!")
print("程式正常退出")
# 此示例示意 try-except語句的用法
def div_apple(n):
print("%d個蘋果您想分給幾個人?" % n)
s = input("請輸入人數: ")
cnt = int(s) # <--此處可能觸發ValueError型別的錯誤
result = n / cnt # <-- 此處可能會觸發ZeroDivisionError型別的錯誤
print("每個人分了%d個蘋果" % result)
try:
div_apple(10) # 此函式可能會觸發錯誤,分蘋果失敗
print("分完蘋果")
except (ValueError, ZeroDivisionError):
print("蘋果不分了")
print("程式正常退出")
# 此示例示意 try-except語句的用法
def div_apple(n):
print("%d個蘋果您想分給幾個人?" % n)
s = input("請輸入人數: ")
cnt = int(s) # <--此處可能觸發ValueError型別的錯誤
result = n / cnt # <-- 此處可能會觸發ZeroDivisionError型別的錯誤
print("每個人分了%d個蘋果" % result)
try:
div_apple(10) # 此函式可能會觸發錯誤,分蘋果失敗
print("分完蘋果")
except ValueError:
print("蘋果不分了")
except:
print("其它型別的錯誤已捕獲!")
print("程式正常退出")
練習:
寫一個函式:
def get_score():
....
此函式來獲取使用者輸入的學生成績資訊(1~100的整數)
如果使用者輸入出現異常則此函式返回0,否則返回使用者輸入的成績
def get_score():
try:
score = int(input("請輸入成績:"))
if 0 <=score <=100 :
return score
else:
return 0
except:
return 0
return score
score = get_score()
print("您輸入的成績是:",score)
#此示例示意 try-except語句中 as 的用法
def div_apple(n):
print("%d個蘋果您想分給幾個人?" % n)
s = input("請輸入人數: ")
cnt = int(s) <--此處可能觸發ValueError型別的錯誤
result = n / cnt <-- 此處可能會觸發ZeroDivisionError型別的錯誤
print("每個人分了%d個蘋果" % result)
try:
div_apple(10) # 此函式可能會觸發錯誤,分蘋果失敗
print("分完蘋果")
except ValueError as e:
print("蘋果不分了")
print("錯誤的值是:", e)
except:
print("其它型別的錯誤已捕獲!")
print("程式正常退出")
try-finally語句
語法:
try:
可能觸發異常的語句
finally:
一定要執行的最終語句
說明:
1.finally 子句不可以省略
2.一定不存在except子句
作用:
通常用try-finally語句來做觸發異常時必須要處理的事情,無論異常是否發生,finally子句都會被執行
注:
try-finally 語句不會改變程式的狀態(正常/異常)狀態
def fry_egg():
print('開啟氣')
try:
count = int(input("雞蛋數:"))
print("共煎了",count,'個雞蛋')
finally:
print("關閉氣")
fry_egg()
raise 語句
作用:
觸發一個錯誤,讓程式進入異常狀態
語法:
raise 異常型別
或
raise 異常物件
# 此示例示意用raise語句來觸發異常
def make_exception():
print("begin")
# 觸發ValueError型別的異常並進入異常狀態
# raise ValueError
err = ValueError("這是我自己定義的一個錯誤")
raise err
print("end")
make_exception()
# try:
# make_exception()
# print("make_exception呼叫結束")
# except ValueError as e:
# print("try裡出現了值錯誤通知,已捕獲!!!")
# print("接收的異常通知是: ", e)
練習:
寫一個函式get_age() 用來獲取一個人的年齡資訊
此函式規則使用者只能輸入1~140之間的整數。如果使用者輸入其他的數則直接觸發
ValueError型別的錯誤!
def get_age():
...
def get_age():
s = input("請輸入年齡(1~140): ")
a = int(s) # int函式裡可能會觸發ValueError型別的錯誤
if 1 <= a <= 140:
return a
raise ValueError("使用者輸入的整數不在1~140之間")
try:
age = get_age()
print("使用者輸入的年齡是:", age)
except ValueError as err:
print("使用者輸入的不是1~140的整數!!,獲取年齡失敗")
assert 語句(斷言語句)
語法:
assert 真值表達式,錯誤資料(通常是字串)
作用:
當真值表示式為False時,用錯誤資料建立一個AssertionError型別的錯誤,並進入異常狀態
等同於:
if 真值表達式== False:
raise AssertionError(錯誤資料)
異常小結:
語句:
try-except
捕獲異常,嘗試接收異常通知
try-finally
執行一定要執行的語句
raise
傳送異常通知,將程式轉為異常狀態(進入異常流程)
assert
根據條件來觸發AssertionError型別的異常
with 語句(以後再學)
為什麼要用異常處理機制
在程式呼叫層數較深時,向主調程式傳遞錯誤資訊需要層層return返回比較麻煩,
所以用異常處理機制來解決此類問題
def f1():
print("開始建房子打地基")
err = ValueError("打地基挖出古董")
raise err
print("完成打地基工作")
return "地基完成"
def f2():
print("開始建設地上部分")
# err = ValueError("規劃要建高壓線")
# return err
print("地上部分建完..")
return "地上完成"
def f3():
# 建地基
r1 = f1()
# 建地上部分
r2 = f2()
return r1 + r2
def built_house():
'''接專案的人'''
return f3()
try:
h = built_house() # 建房子的函式,此函式應當返回一個房子物件
print(h)
except ValueError as e:
print("錯誤原因是:", e)
print('改建博物管')
練習:
1.一個球從100米高空落下,每次落地後反彈高度為原高度的一半,在落下,寫程式
1)算出皮球在第10次落地後反彈多高
2)列印除皮球共經歷了多少米路程
2.分解質因數,輸入一個正整數,分解質因數
如輸入:90,則列印:
90= 2* 3 * 3 * 5
(質因數是指最小能被原數整除的素數(不包含1))
3.寫程式列印楊輝三角(只打印6層)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
# 1) 算出皮球在第10次落地後反彈多高
# 用循來來實現
def get_last_height(height, times):
for _ in range(times):
height /= 2
return height
# 用遞迴來實現
# def get_last_height(height, times):
# if times == 0:
# return 100
# return get_last_height(height, times - 1) / 2
print(get_last_height(100, 10))
# 2) 打印出皮球共經歷了多少米路程
def get_distance(height, times):
s = 0
for _ in range(times):
s += height + height / 2
height /= 2
return s
print(get_distance(100, 10))
#2
def is_prime(x):
if x < 2:
return False
for i in range(2, x):
if x % i == 0:
return False
# else:
# return True
return True
def get_yinshu_list(n):
'''用迴圈實現'''
L = [] # 用來存放所有的質因數
x = n # x代表未分解的數
while not is_prime(x): # 當x不是素數時開始迴圈
for i in range(2, x):
if x % i == 0 and is_prime(i): # 被整除,i是質因數
L.append(i)
x = int(x / i)
break
L.append(x)
return L
n = int(input("請輸入一個正整數: "))
# print(get_yinshu_list(n))
yinshu = get_yinshu_list(n)
s = '*'.join([str(x) for x in yinshu])
print("%d = %s" % (n, s))
#3.
def get_yanghui_list(n): # n代表層數
'''此函式用於返回每一層的列表的列表'''
layers = [] # 用於儲存每一行的資料[[1], [1, 1], [1, 2, 1], ...]
L = [1]
for _ in range(n): # 迴圈,每次加入layers中一行
layers.append(L) # 先把第一行加入
# 算出下一行。再用L重新繫結
one_line = [1] # 最左邊的1
# 算出中間的數字
for i in range(len(L) - 1):
one_line.append(L[i] + L[i + 1])
one_line.append(1) # 加入最右邊的1
L = one_line # 讓L 繫結新算出的一行
return layers
if __name__ == '__main__':
# print(get_yanghui_list(6))
for l in get_yanghui_list(6):
print(l)