Python day_9 第一部分完结撒花!!

1.使用 try-except 代码块

当你认为可能发生了错误时,可编写一个try-except代码块来处理可能引发的异常。你让Python尝试运行一些代码,并告诉它如果这些代码引发了指定的异常,该怎么办:

try: 
	 print(5/0) 
	 
except ZeroDivisionError: 
	 print("You can't divide by zero!") 

我们将导致错误的代码行print(5/0)放在了一个try代码块中。如果try代码块中的代码运行起来没有问题,Python将跳过except代码块;如果try代码块中的代码导致了错误,Python将查找这样的except代码块,并运行其中的代码,即其中指定的错误与引发的错误相同。在这个示例中,try代码块中的代码引发了ZeroDivisionError异常,因此Python指出了该如何解决问题的except代码块,并运行其中的代码。这样,用户看到的是一条友好的错误消息,而不是traceback:
You can’t divide by zero!

2.else代码块

依赖于try代码块成功执行的代码都应放到else代码块中:

print("Give me two numbers, and I'll divide them.") 
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代码块中;在这个示例中,如果除法运算成功,我们就使用else代码块来打印结果

3.处理FileNotFoundError 异常

使用文件时,一种常见的问题是找不到文件:你要查找的文件可能在其他地方、文件名可能不正确或者这个文件根本就不存在。对于所有这些情形,都可使用try-except代码块以直观的方式进行处理。

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) 
4.分析文本

我们将使用方法split(),它根据一个字符串创建一个单词列表。

>>> title = "Alice in Wonderland" 
>>> title.split() 
['Alice', 'in', 'Wonderland'] 

方法split()以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。结果是一个包含字符串中所有单词的列表,虽然有些单词可能包含标点。

分析文本有多少个单词

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.") 
5.使用多个文件
def count_words(filename): 
	 """计算一个文件大致包含多少个单词""" 
  	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.") 
  
filename = 'alice.txt' 
countwords(filename) 

分别计算多本书的单词数:

def count_words(filename): 
	 --snip-- 
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt'] 
for filename in filenames: 
	 count_words(filename)
6.失败时一声不吭

有时候你希望程序在发生异常时一声不吭,就像什么都没有发生一样继续运行。要让程序在失败时一声不吭,可像通常那样编写try代码块,但在except代码块中明确地告诉Python什么都不要做。Python有一个pass语句,可在代码块中使用它来让Python什么都不要做。

try:
------
except FileNotFoundError:
pass

pass语句还充当了占位符,它提醒你在程序的某个地方什么都没有做,并且以后也许要在这里做些什么。

7.使用json.dump()和json.load()
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,再创建一个数字列表。在Ø处,我们指定了要将该数字列表存储到其中的文件的名称。通常使用文件扩展名.json来指出文件存储的数据为JSON格式。接下来,我们以写入模式打开这个文件,让json能够将数据写入其中。我们使用函数json.dump()将数字列表存储到文件numbers.json中。

import json 

filename = 'numbers.json' 
with open(filename) as f_obj: 
	numbers = json.load(f_obj) 
 
print(numbers) 

这是一种在程序之间共享数据的简单方式。

8.可通过测试

方法名必须以test_打头,这样它才会在我们运行test_name_function.py时自动运行。

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

首先,我们导入了模块unittest和要测试的函数get_formatted_ name()。我们创建了一个名为NamesTestCase的类,这个类必须继承unittest.TestCase类,这样Python才知道如何运行你编写的测试。NamesTestCase只包含一个方法,用于测试get_formatted_name()的一个方面。我们将这个方法命名为test_first_last_name(),因为我们要核实的是只有名和姓的姓名能否被正确地格式化。我们运行test_name_function.py时,所有以test_打头的方法都将自动运行。在这个方法中,我们调用了要测试的函数,并存储了要测试的返回值。在这个示例中,我们使用实参’janis’和’joplin’调用get_formatted_name(),并将结果存储到变量formatted_name中。

我们使用了unittest类最有用的功能之一:一个断言方法。断言方法用来核实得到的结果是否与期望的结果一致。在这里,我们知道get_formatted_name()应返回这样的姓名,即名和姓的首字母为大写,且它们之间有一个空格,因此我们期望formatted_name的值为Janis Joplin。为检查是否确实如此,我们调用unittest的方法assertEqual(),并向它传递formatted_ name和’Janis Joplin’。代码行self.assertEqual(formatted_name, ‘Janis Joplin’)的意思是说:“将formatted_name的值同字符串’Janis Joplin’进行比较,如果它们相等,就万事大吉,如果它们不相等,跟我说一声!”

测试未通过时怎么办呢?如果你检查的条件没错,测试通过了意味着函数的行为是对的,而测试未通过意味着你编写的新代码有错。因此,测试未通过时,不要修改测试,而应修复导致测试不能通过的代码:检查刚对函数所做的修改,找出导致函数行为不符合预期的修改。

9.测试类

Python在unittest.TestCase类中提供了很多断言方法。
断言方法检查你认为应该满足的条件是否确实满足。如果该条件确实满足,你对程序行为的假设就得到了确认,你就可以确信其中没有错误。如果你认为应该满足的条件实际上并不满足,Python将引发异常。

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

AnonymousSurvey类可用于进行简单的匿名调查

10.测试 AnonymousSurvey 类

对AnonymousSurvey类的行为的一个方面进行验证:如果用户面对调查问题时只提供了一个答案,这个答案也能被妥善地存储。

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() 
11.方法setUp()

unittest.TestCase类包含方法setUp(),让我们只需创建这些对象一次,并在每个测试方法中使用它们。如果你在TestCase类中包含了方法setUp(),Python将先运行它,再运行各个以test_打头的方法。这样,在你编写的每个测试方法中都可使用在方法setUp()中创建的对象了

注意 运行测试用例时,每完成一个单元测试,Python都打印一个字符:测试通过时打印一个句点;测试引发错误时打印一个E;测试导致断言失败时打印一个F。这就是你运行测试用例时,在输出的第一行中看到的句点和字符数量各不相同的原因。如果测试用例包含很多单元测试,需要运行很长时间,就可通过观察这些结果来获悉有多少个测试通过了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值