1. 程式人生 > >(十四)python 包的相對匯入,異常,try,raise語句,assert語句

(十四)python 包的相對匯入,異常,try,raise語句,assert語句

目錄

    try語句

異常小結:

__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)