Python Revisited Day 04 (控制結(jié)構(gòu)與函數(shù))

《Python 3 程序開發(fā)指南》 學(xué)習(xí)筆記

image.png

4.1 控制結(jié)構(gòu)

4.1.1 條件分支

if ....:
    suite1
elif ...:
    suite2
...
elif ...:
    suiteN
else:
    suite_else

條件表達(dá)式

expression1 if boolean_expression else expression2
import random
999 if random.random() > 0.5 else 0  #999 or 0
999 + 1 if random.random() > 0.5 else 0  # 1000 or 0
999 + (1 if random.random() > 0.5 else 0) # 1000 or 999

4.1.2 循環(huán)

4.1.2.1 while循環(huán)

while boolean_expression:
    while_suite
else: #有些時候還蠻有用的 循環(huán)正常執(zhí)行結(jié)束后執(zhí)行
    else_suite

4.1.2.2 for循環(huán)

for expression in iterable:
    for_suite
else: #循環(huán)正常結(jié)束后執(zhí)行
    else_suite
for i in range(5):
    print(i)
else:
    print('!!!!')
0
1
2
3
4
!!!!
for i in range(5):
    if i == 3:
        break
    print(i)
else:
    print('!!!!')
0
1
2

return 同樣會跳過else_suite

4.2 異常處理

4.2.1 捕獲與產(chǎn)生異常

try:
    try_suite
except exception_group1 as variable1:
    except_suite1
...
except exception_group1 as variable1:
    except_suiteN
else: #try部分正常執(zhí)行才會執(zhí)行這部分
    else_suite
finally: #總會執(zhí)行  即便異常沒有被捕獲到 往往用于確保資源被正確釋放
    finally_suite

更加簡單的try...finally...

try:
    try_suite
finally:
    finally_suite

產(chǎn)生異常 raise

raise exception(args)
raise exception(args) from original_exception
raise
raise KeyError('dasd')  # KeyError: 'dasd'

4.2.2 自定義異常

class exceptionName(baseException): pass

注意:上面的baseException是指某個已存在的關(guān)于異常的類

class WAWAWAError(KeyError):
    pass

tips 用異常跳出深層嵌套循環(huán)

flag = False
for i in range(9):
    for j in range(9):
        for k in range(9):
            if i + j +k > 10:
                flag = True
                break
        if flag:
            break
    if flag:
        break
else:
    print(flag)

當(dāng)i + j + k > 10的時候碳胳,我們希望能跳出循環(huán),雖然這個代碼塊的樣子還挺帥的裆泳,但是很蠢吧舌界。

class ExitException(Exception): pass
try:
    for i in range(9):
        for j in range(9):
            for k in range(9):
                if i + j +k > 10:
                    raise ExitException()
except ExitException:
    
    print('Come on!')
else:
    print('You will not see me!')

4.3 自定義函數(shù)

Tips 參數(shù)默認(rèn)值為可變時 危險

給定默認(rèn)值的時候缰儿,參數(shù)時在程序執(zhí)行def時就建立的了,所以,當(dāng)參數(shù)默認(rèn)值為可變對象的時候寡壮,危險尚氛。

def append_if_even(x, lst=[]):  #從對象綁定的角度考慮诀诊,合情合理
    if x % 2 == 0:
        lst.append(x)
    print(lst)

append_if_even(2) #[2]
append_if_even(2) #[2, 2] 
append_if_even(2) #[2, 2, 2]
append_if_even(2) #[2, 2, 2, 2]

字符串 數(shù)字 元組等都是固定變量

def append_if_even(x, lst=''):
    if x % 2 == 0:
        lst += '?'
    print(lst)
append_if_even(2) # '?'
append_if_even(2) # '?'
append_if_even(2) # '?'
append_if_even(2) # '?'
def append_if_even(x, lst=None):
    lst = [] if lst is None else lst
    if x % 2 == 0:
        lst += '?'
    print(lst)

4.3.1 名稱與Docstrings

def simpledoc(real, dream='sky'):
    """ Returns the text I can not control now...
    
    real is any string; dream is the same as well, while it has default value 'sky'.
    Of course, your different people has various dreams, but we all need to confront 
    the real life.
    >>> simpledoc('god')
    "haha happy"
    >>> simpledoc('god', 'earth')
    "don't cry, go forward..."
    """
    if real == 'god' and dream == 'sky':
        return 'haha happy'
    else:
        return "don't cry, go forward..."

4.3.2 參數(shù)與參數(shù)拆分

def product(*args):
    print(args)
    result = 1
    for arg in args:
        result += arg
    return result
product(2,3,4,5) # (2, 3, 4, 5)  15

*args 后面仍然可以使用關(guān)鍵詞參數(shù)

def sum_of_powers(*args, power=1): #雖然power不添加默認(rèn)值不會報錯,但是使用的時候必須用關(guān)鍵詞參數(shù)的形式傳入值
    result = 0
    for arg in args:
        result += arg ** power
    return result

* 用于區(qū)分位置參數(shù)和關(guān)鍵詞參數(shù) def f(a, b, *, c = 0): ...

def sum_and_add(a, b, *, c = 0):
    return a + b + c

sum_and_add(1, 2)   # 3
sum_and_add(1, 2, 1) #TypeError
sum_and_add(1, 2, c = 1) # 4

f(**options)

**用于傳入?yún)?shù)

options = dict(a = 1, b = 2, c = 1) #如果有多余的參數(shù)阅嘶,會TypeError
sum_and_add(**options) # 4

**用于函數(shù)構(gòu)建

def add(prime = 0, **adds):
    for key, value in adds.items():
        print(key)
        prime += value
    return prime

add(a = 1, b = 2, c = 3) # a b c 6

4.3.3 存取全局范圍的變量 global

def remain():
    global REMAIN
    REMAIN = 3
def sum_and_add(a, b):
    remain() #得執(zhí)行一次
    return a + b + REMAIN
sum_and_add(1, 2) # 6

4.3.4 Lambda 函數(shù)

lambda parameters: expression

expression 不能包含分支或循環(huán)属瓣,也不能包含return或yield。如果expression是一個元組讯柔,那么應(yīng)該用括號包起來抡蛙。

f = lambda : (1, 2)
f() # (1, 2)
f = lambda x: "" if x == 1 else 's'
f(1) # ''  

4.3.5 斷言 assert

assert boolean_expression, optional_expression
def product(*args):
    assert all(args), "0 argument"
    result = 1
    for arg in args:
        result *= arg
        
    return result

product(*[1, 2, 3, 4]) # 24
在這里插入圖片描述

練習(xí)


import os
import sys


WORD_FORWARD = "Choose filename: "
WORD_CONTINUE = "Press Enter to continue..."
WORD_OPTION1 = "[A/a]dd [D/d]elete [S/s]ave    [Q/q]uit [a]: "
WORD_OPTION2 = "[A/a]dd [Q/q]uit [a]: "
WORD_ERROR_FILENAME = "Sorry, {0} is not found..."
WORD_ERROR_OPTION1 = "ERROR: invalid choice--enter one of 'AaDdSsQq'"
WORD_ERROR_OPTION2 = "ERROR: invalid choice--enter one of 'AaQq'"
WORD_FILES_ZERO = "-- no items are in list --"
WORD_ADD_ITEM = "Add item: "
WORD_DELETE_ITEM = "Delete item number (or 0 to cancel): "
WORD_ERROR_DELETE = "The number exceeds the limits..."
WORD_SAVE_ITEM = "Saved {0} item{1} to {2}"
WORD_SAVE_UNSAVED = "Save unsaved changes (y/n) [y]: "

def filename_and_set():
    f = None
    files = []
    global filename
    try:
        filename = input(WORD_FORWARD)
        if filename[-4:] != '.txt':  #.txt 代替.lst
            filename += '.txt'

        f = open(filename)
        for item in f:
            files.append(item.rstrip())
    except FileNotFoundError:
        pass
    finally:
        if f is not None:
            f.close()
    return files

def delete_item(files):

    flag = input(WORD_DELETE_ITEM)
    try:
        flag = int(flag)
        if flag is 0:
            pass
        else:
            files.pop(flag - 1)
    except ValueError:
        print("Integer is need...")
    except IndexError:
        print(WORD_ERROR_DELETE)
def save_item(files):
    f = None
    n = len(files)
    try:
        f = open(filename, 'w', encoding='utf8')
        for item in files:
            f.write(item + '\n')
        print(WORD_SAVE_ITEM.format(n,
                                    's' if n > 1 else '',
                                    filename))
    except:
        print('ERROR: SAVE...')
    finally:
        if f is not None:
            f.close()

def quit_item(files):

    n = len(files)
    flag = input(WORD_SAVE_UNSAVED)
    if flag is 'y' or not flag:

        save_item(files)

    sys.exit()

def option1(files, label):

    if label == 'A' or label == 'a' or not label:

        files.append(input(WORD_ADD_ITEM))

    elif label == 'D' or label == 'd':

        delete_item(files)

    elif label == 'S' or label =='s':

        save_item(files)

    elif label == 'Q' or label == 'q':
        quit_item(files)
    else:
        print(WORD_ERROR_OPTION1)


def option2(files, label):
    if label == 'A' or label == 'a' or not label:

        files.append(input(WORD_ADD_ITEM))

    elif label == 'Q' or label == 'q':

        quit_item(files)

    else:
        print(WORD_ERROR_OPTION2)

def screen_show(files):

    n = len(files)
    if n != 0:
        files.sort()

    if not n:
        print(WORD_FILES_ZERO)
        label = input(WORD_OPTION2)
        option2(files, label)
    else:
        for i in range(n):
            print("{0}: {1}".format(i+1, files[i]))
        label = input(WORD_OPTION1)
        option1(files, label)




def main():

    files = filename_and_set()
    count = 1
    while True:
        count += 1
        if count > 10:
            break
        screen_show(files)
        print('\n\n')

main()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市魂迄,隨后出現(xiàn)的幾起案子粗截,更是在濱河造成了極大的恐慌,老刑警劉巖捣炬,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件熊昌,死亡現(xiàn)場離奇詭異绽榛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)婿屹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進(jìn)店門灭美,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人选泻,你說我怎么就攤上這事冲粤。” “怎么了页眯?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵梯捕,是天一觀的道長。 經(jīng)常有香客問我窝撵,道長傀顾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任碌奉,我火速辦了婚禮短曾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赐劣。我一直安慰自己嫉拐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布魁兼。 她就那樣靜靜地躺著婉徘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咐汞。 梳的紋絲不亂的頭發(fā)上盖呼,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天,我揣著相機(jī)與錄音化撕,去河邊找鬼几晤。 笑死,一個胖子當(dāng)著我的面吹牛植阴,可吹牛的內(nèi)容都是我干的蟹瘾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼掠手,長吁一口氣:“原來是場噩夢啊……” “哼热芹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惨撇,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎府寒,沒想到半個月后魁衙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體报腔,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年剖淀,在試婚紗的時候發(fā)現(xiàn)自己被綠了纯蛾。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡纵隔,死狀恐怖翻诉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捌刮,我是刑警寧澤碰煌,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站绅作,受9級特大地震影響芦圾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜俄认,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一个少、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧眯杏,春花似錦夜焦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至河闰,卻和暖如春科平,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姜性。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工瞪慧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人部念。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓弃酌,卻偏偏與公主長得像,于是被迫代替她去往敵國和親儡炼。 傳聞我的和親對象是個殘疾皇子妓湘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評論 2 355