《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()