文章目录
4.1 控制结构
4.1.1 条件分支
if ....: suite1elif ...: suite2...elif ...: suiteNelse: suite_else
条件表达式
expression1 if boolean_expression else expression2
import random999 if random.random() > 0.5 else 0 #999 or 0
999 + 1 if random.random() > 0.5 else 0 # 1000 or 0999 + (1 if random.random() > 0.5 else 0) # 1000 or 999
4.1.2 循环
4.1.2.1 while循环
while boolean_expression: while_suiteelse: #有些时候还蛮有用的 循环正常执行结束后执行 else_suite
4.1.2.2 for循环
for expression in iterable: for_suiteelse: #循环正常结束后执行 else_suite
for i in range(5): print(i)else: print('!!!!')
01234!!!!
for i in range(5): if i == 3: break print(i)else: print('!!!!')
012
return 同样会跳过else_suite
4.2 异常处理
4.2.1 捕获与产生异常
try: try_suiteexcept exception_group1 as variable1: except_suite1...except exception_group1 as variable1: except_suiteNelse: #try部分正常执行才会执行这部分 else_suitefinally: #总会执行 即便异常没有被捕获到 往往用于确保资源被正确释放 finally_suite
更加简单的try…finally…
try: try_suitefinally: finally_suite
产生异常 raise
raise exception(args)raise exception(args) from original_exceptionraise
raise KeyError('dasd') # KeyError: 'dasd'
4.2.2 自定义异常
class exceptionName(baseException): pass
注意:上面的baseException是指某个已存在的关于异常的类
class WAWAWAError(KeyError): pass
tips 用异常跳出深层嵌套循环
flag = Falsefor 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: breakelse: print(flag)
当i + j + k > 10的时候,我们希望能跳出循环,虽然这个代码块的样子还挺帅的,但是很蠢吧。
class ExitException(Exception): passtry: 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 自定义函数
Tips 参数默认值为可变时 危险
给定默认值的时候,参数时在程序执行def时就建立的了,所以,当参数默认值为可变对象的时候,危险。
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]
字符串 数字 元组等都是固定变量
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 参数与参数拆分
def product(*args): print(args) result = 1 for arg in args: result += arg return resultproduct(2,3,4,5) # (2, 3, 4, 5) 15
*args 后面仍然可以使用关键词参数
def sum_of_powers(*args, power=1): #虽然power不添加默认值不会报错,但是使用的时候必须用关键词参数的形式传入值 result = 0 for arg in args: result += arg ** power return result
* 用于区分位置参数和关键词参数 def f(a, b, *, c = 0): …
def sum_and_add(a, b, *, c = 0): return a + b + csum_and_add(1, 2) # 3sum_and_add(1, 2, 1) #TypeErrorsum_and_add(1, 2, c = 1) # 4
f(**options)
**用于传入参数
options = dict(a = 1, b = 2, c = 1) #如果有多余的参数,会TypeErrorsum_and_add(**options) # 4
**用于函数构建
def add(prime = 0, **adds): for key, value in adds.items(): print(key) prime += value return primeadd(a = 1, b = 2, c = 3) # a b c 6
4.3.3 存取全局范围的变量 global
def remain(): global REMAIN REMAIN = 3def sum_and_add(a, b): remain() #得执行一次 return a + b + REMAINsum_and_add(1, 2) # 6
4.3.4 Lambda 函数
lambda parameters: expression
expression 不能包含分支或循环,也不能包含return或yield。如果expression是一个元组,那么应该用括号包起来。
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 resultproduct(*[1, 2, 3, 4]) # 24
练习
import osimport sysWORD_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 filesdef 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()