Chapter10
2020-04-11 20:09:04
程序崩溃可不好,但让用户看到traceback也不是好主意。如果用户怀有恶意,他会通过traceback获悉你不希望他知道的信息。有时候,训练有素的攻击者可根据这些信息判断出可对你的代码发起什么样的攻击。
try-except 代码块
执行第一段语句,若存在错误,不会报警,而会转向except语句。借此提高这个程序抵御错误的能力。except后记得加错误名。
try: print(5/0) except ZeroDivisionError: print("You can't divide by zero!")
try-except-else代码块
print("Enter 'q' to quit.") while True: first_number = input("\nFirst number: ") if first_number == 'q': break second_number = input("Second number: ") try: answer = int(first_number) / int(second_number) except ZeroDivisionError: print("You can't divide by 0!") else: print(answer)
依赖于try 代码块成功执行的代码都放在else 代码块中。except-else是try判断后的两个分支。
通过预测可能发生错误的代码,可编写健壮的程序,它们即便面临无效数据或缺少资源,也能继续运行,从而能够抵御无意的用户错误和恶意的攻击。
分析文本:
filename = 'alice.txt' try: with open(filename) as f_obj: contents = f_obj.read() except FileNotFoundError: msg = "Sorry, the file " + filename + " does not exist." print(msg) else: # 计算文件大致包含多少个单词 words = contents.split() num_words = len(words) print("The file " + filename + " has about " + str(num_words) + " words.")
[1]方法split() 以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。
存储数据:
import json numbers = [2, 3, 5, 7, 11, 13] filename = 'numbers.json' with open(filename, 'w') as f_obj: json.dump(numbers, f_obj)
函数json.dump() 将数字列表存储到文件numbers.json中。
后续读取:
import json filename = 'numbers.json' with open(filename) as f_obj: numbers = json.load(f_obj) print(numbers)
保存和读取用户生成的数据:
#读取并存储用户名 import json username = input("What is your name? ") filename = 'username.json' with open(filename, 'w') as f_obj: json.dump(username, f_obj) print("We'll remember you when you come back, " + username + "!") #调用文件并读取 import json filename = 'username.json' with open(filename) as f_obj: username = json.load(f_obj) print("Welcome back, " + username + "!")
合并为新文件:
import json # 如果以前存储了用户名,就加载它 # 否则,就提示用户输入用户名并存储它 filename = 'username.json' try: with open(filename) as f_obj: username = json.load(f_obj) except FileNotFoundError: username = input("What is your name? ") with open(filename, 'w') as f_obj: json.dump(username, f_obj) print("We'll remember you when you come back, " + username + "!") else: print("Welcome back, " + username + "!")
重构:将代码划分为一系列完成具体工作的函数
import json def get_stored_username(): """如果存储了用户名,就获取它""" --snip-- def get_new_username(): """提示用户输入用户名""" username = input("What is your name? ") filename = 'username.json' with open(filename, 'w') as f_obj: json.dump(username, f_obj) return username def greet_user(): """问候用户,并指出其名字""" username = get_stored_username() if username: print("Welcome back, " + username + "!") else: username = get_new_username() print("We'll remember you when you come back, " + username + "!") greet_user()
Chapter11 测试函数
导入模块unittest 以及要测试的函数,再创建一个继承unittest.TestCase 的类,并编写一系列方法对函数行为的不同方面进行测试。
待测试函数:
#name_function.py def get_formatted_name(first, last): #Generate a neatly formatted full name. full_name = first + ' ' + last return full_name.title() #test import unittest from name_function import get_formatted_name class NamesTestCase(unittest.TestCase): #测试name_function.py def test_first_last_name(self): #能够正确地处理像Janis Joplin这样的姓名吗? formatted_name = get_formatted_name('janis', 'joplin') self.assertEqual(formatted_name, 'Janis Joplin') unittest.main()
[1]assertEqual: 断言方法用来核实得到的结果是否与期望的结果一致。注意是否有顺序要求!
类的测试:
原类:
class AnonymousSurvey(): #收集匿名调查问卷的答案""" def __init__(self, question): #存储一个问题,并为存储答案做准备""" self.question = question self.responses = [] def show_question(self): #显示调查问卷""" print(question) def store_response(self, new_response): #存储单份调查答卷""" self.responses.append(new_response) def show_results(self): #显示收集到的所有答卷""" print("Survey results:") for response in responses: print('- ' + response)
调用:
from survey import AnonymousSurvey #定义一个问题,并创建一个表示调查的AnonymousSurvey对象 question = "What language did you first learn to speak?" my_survey = AnonymousSurvey(question) #显示问题并存储答案 my_survey.show_question() print("Enter 'q' at any time to quit.\n") while True: response = input("Language: ") if response == 'q': break my_survey.store_response(response) # 显示调查结果 print("\nThank you to everyone who participated in the survey!") my_survey.show_results()
测试:
import unittest from survey import AnonymousSurvey class TestAnonmyousSurvey(unittest.TestCase): #针对AnonymousSurvey类的测试""" def test_store_single_response(self): #测试单个答案会被妥善地存储""" question = "What language did you first learn to speak?" my_survey = AnonymousSurvey(question) my_survey.store_response('English') self.assertIn('English', my_survey.responses) unittest.main()
接下来就是本书的项目环节了。