python编程从入门到实践笔记
python编程从入门到实践
第二章 变量和简单数据类型
字符串
常用方法
1 | title() #首字母大写 |
f字符串
要在字符串中插入变量的值,可在前引号前加上字母 f,再将要插入的变量放在花括号内。
1 | first_name = "ada" |
format()方法
1 | full_name = "{} {}".format(first_name, last_name) |
删除空白
1 | rstrip() #删除字符串末尾的空白 |
数
下划线
书写很大的数时,可使用下划线将其中的数字分组,使其更清晰易读
1 | universe_age = 14_000_000_000 #Python 不会打印其中的下划线 |
同时给多个变量赋值
1 | x, y, z = 0, 0, 0 |
常量
常量命名时字母全部大写
Python之禅
1 | import this |
第三章 列表简介
列表简介
列表由一系列按特定顺序排列的元素组成。
在 Python 中,用方括号([])表示列表,并用逗号分隔其中的元素。
访问列表
1 | bicycles = ['trek', 'cannondale', 'redline', 'specialized'] |
索引从0开始
没什么好解释的,懂得都懂 :joy:
修改、添加和删除元素
修改
1 | motorcycles = ['honda', 'yamaha', 'suzuki'] |
添加
append
:在末尾插入
1 | motorcycles.append('ducati') |
insert()
:在任意位置插入
1 | motorcycles = ['honda', 'yamaha', 'suzuki'] |
删除
del
:删除任意位置元素
1 | motorcycles = ['honda', 'yamaha', 'suzuki'] |
pop()
:删除列表末尾的元素,并让你能够接着使用它。
1 | motorcycles = ['honda', 'yamaha', 'suzuki'] |
pop()也可以删除任意位置元素
1 | motorcycles = ['honda', 'yamaha', 'suzuki'] |
remove
:根据值删除元素 (只删除第一个指定的值)
1 | motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati'] |
组织列表
永久排序
sort
:按字母顺序排列
1 | cars = ['bmw', 'audi', 'toyota', 'subaru'] |
sort
:按字母顺序相反顺序排列
1 | cars = ['bmw', 'audi', 'toyota', 'subaru'] |
临时排序
sorted
:调用函数 sorted()后,列表元素的排列顺序并没有变。如果要按与字母顺序 相反的顺序显示列表,也可向函数 sorted()传递参数 reverse=True。
倒着打印列表
reverse()
:反转列表元素的排列顺序
1 | cars = ['bmw', 'audi', 'toyota', 'subaru'] |
确定列表的长度
len()
:可快速获悉列表的长度
1 | cars = ['bmw', 'audi', 'toyota', 'subaru'] |
使用列表时避免索引错误
索引从0开始
索引-1 总是返回最后一个列表元素
第四章 操作列表
遍历整个列表
for循环
:
1 | magicians = ['alice', 'david', 'carolina'] |
避免缩进错误
Python 根据缩进来判断代码行与前一个代码行的关系。
忘记缩进
忘记缩进额外的代码行
不必要的缩进
循环后不必要的缩进
遗漏了冒号
for 语句末尾的冒号告诉 Python,下一行是循环的第一行。
创建数值列表
使用函数 range()
1 | for value in range(1, 5): |
只会打印从1到4的数,到第二个值时停止
使用 range()创建数字列表
要创建数字列表,可使用函数 list()将 range()的结果直接转换为列表。如果将 range()作 为 list()的参数,输出将是一个数字列表。
1 | numbers = list(range(1, 6)) |
1 | even_numbers = list(range(2, 11, 2)) #从 2 开始数,然后不断加 2,直到达到或超过终值 |
**
表示乘方运算
1 | square = value ** 2 #相当于平方 |
简单统计计算
1 | min() |
列表解析
列表解析将 for 循环和创建新元素的代码合并成一行,并自动附加新元素。
1 | squares = [value**2 for value in range(1, 11)] |
使用列表的一部分
切片
要创建切片,可指定要使用的第一个元素和最后一个元素的索引。
与函数 range()一样, Python 在到达第二个索引之前的元素后停止。
1 | players = ['charles', 'martina', 'michael', 'florence', 'eli'] |
如果没有指定第一个索引,Python 将自动从列表开头开始。
1 | players = ['charles', 'martina', 'michael', 'florence', 'eli'] |
让切片终止于列表末尾。
1 | players = ['charles', 'martina', 'michael', 'florence', 'eli'] |
负数索引返回离列表末尾相应距离的元素,因此你可以输出列表末尾的任意切片。例如,如果要 输出名单上的最后三名队员,可使用切片 players[-3:]
1 | players = ['charles', 'martina', 'michael', 'florence', 'eli'] |
可在表示切片的方括号内指定第三个值。这个值告诉 Python 在指定范围内每隔多少元素 提取一个。
遍历切片
如果要遍历列表的部分元素,可在 for 循环中使用切片。
复制列表
要复制列表,可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引([:])。 这让 Python 创建一个始于第一个元素、终止于最后一个元素的切片,即整个列表的副本。
1 | my_foods = ['pizza', 'falafel', 'carrot cake'] |
1 | my_foods = ['pizza', 'falafel', 'carrot cake'] |
这里将 my_foods 赋给 friend_foods,而不是将 my_foods 的副本赋给 friend_foods(见)。 这种语法实际上是让 Python 将新变量 friend_foods 关联到已与 my_foods 相关联的列表,因此这 两个变量指向同一个列表。
元组
Python 将不能修改的值称为不可变的,而不可变的列表被称为元组。
定义元组
元组看起来很像列表,但使用圆括号而非中括号来标识。
1 | dimensions = (200, 50) |
遍历元组中的所有值
采用for循环
修改元组变量
虽然不能修改元组的元素,但可以给存储元组的变量赋值。
1 | dimensions = (200, 50) |
设置代码格式
缩进
PEP 8 建议每级缩进都使用四个空格。
行长
很多 Python 程序员建议每行不超过 80 字符。
在大多数编辑器中,可以设置一个视觉标志(通常是一条竖线),让你知道不能越过的界线在什么地方
空行
将程序的不同部分分开,可使用空行。
第五章 if语句
简单示例
1 | cars = ['audi', 'bmw', 'subaru', 'toyota'] |
条件测试
每条 if 语句的核心都是一个值为 True 或 False 的表达式,这种表达式称为条件测试
检查是否相等
==
使用两个等号`
检查是否相等时忽略大小写
1 | car = 'Audi' |
检查是否不相等
!=
使用!=
检查多个条件
使用 and 检查多个条件
1 | age_0 = 22 |
使用 or 检查多个条件
1 | age_0 = 22 |
检查特定值是否包含在列表中
使用关键字in
1 | requested_toppings = ['mushrooms', 'onions', 'pineapple'] |
检查特定值是否不包含在列表中
使用关键字not in
1 | banned_users = ['andrew', 'carolina', 'david'] |
if 语句
if-else语句
1 | age = 17 |
if-elif-else结构
1 | age = 12 |
也可以省略else代码块
第六章 字典
一个简单的字典
1 | alien_0 = {'color': 'green', 'points': 5} |
使用字典
在 Python 中,字典是一系列键值对。每个键都与一个值相关联,你可使用键来访问相关联 的值。
键值对是两个相关联的值。指定键时,Python 将返回与之相关联的值。键和值之间用冒号分 隔,而键值对之间用逗号分隔。
访问字典中的值
1 | alien_0 = {'color': 'green'} |
添加键值对
字典是一种动态结构,可随时在其中添加键值对。要添加键值对,可依次指定字典名、用方 括号括起的键和相关联的值。
1 | alien_0 = {'color': 'green', 'points': 5} |
先创建一个空字典
1 | alien_0 = {} |
修改字典中的值
1 | alien_0 = {'color': 'green'} |
删除键值对
可使用 del 语句将相应的键值对彻底删除
1 | alien_0 = {'color': 'green', 'points': 5} |
使用 get()来访问值
可使用方法 get()在指定的键不存在时返回一个默认值,从而避免这样的错误
方法 get()的第一个参数用于指定键,是必不可少的;第二个参数为指定的键不存在时要返 回的值,是可选的
1 | alien_0 = {'color': 'green', 'speed': 'slow'} |
如果字典中有键’points’,将获得与之相关联的值;如果没有,将获得指定的默认值。虽然这里没有键’points’,但将获得一条清晰的消息,不会引发错误
调用 get()时,如果没有指定第二个参数且指定的键不存在,Python 将返回值 None。这 个特殊值表示没有相应的值。None 并非错误,而是一个表示所需值不存在的特殊值
遍历字典
遍历所有键值对
1 | user_0 = { |
方法 items()返回一个键值对列表。
遍历字典中的所有键
在不需要使用字典中的值时,方法 keys()很有用。
1 | favorite_languages = { |
遍历字典时,会默认遍历所有的键
按特定顺序遍历字典中的所有键
从 Python 3.7 起,遍历字典时将按插入的顺序返回其中的元素。
要以特定顺序返回元素,一种办法是在 for 循环中对返回的键进行排序。使用函数sorted()
遍历字典中的所有值
对字典包含的值感兴趣,可使用方法 values()来返回一个值列表,不包含任何键。
为剔除重复项,可使用集合(set)。 集合中的每个元素都必须是独一无二的。
1 | for language in set(favorite_languages.values()): |
集合和字典很容易混淆,因为它们都是用一对花括号定义的。当花括号内没有键值对时, 定义的很可能是集合。不同于列表和字典,集合不会以特定的顺序存储元素。
嵌套
有时候,需要将一系列字典存储在列表中,或将列表作为值存储在字典中,这称为嵌套。
在列表中储存字典
1 | alien_0 = {'color': 'green', 'points': 5} |
在字典中存储列表
1 | # 存储所点比萨的信息。 |
第七章 用户输入和 while 循环
函数 input()的工作原理
1 | message = input("Tell me something, and I will repeat it back to you: ") |
函数 input()接受一个参数——要向用户显示的提示(prompt)或说明,让用户知道该如何做。
使用 int()来获取数值输入
使用函数 input()时,Python将用户输入解读为字符串。
函数 int()将数的字符 串表示转换为数值表示
1 | height = input("How tall are you, in inches? ") |
求模运算符
求模运算符(%)是个很有用的工具,它将两个数相除并返回余数。
while循环
1 | prompt = "\nTell me something, and I will repeat it back to you:" |
使用break退出循环
1 | prompt = "\nPlease enter the name of a city you have visited:" |
在循环中使用continue
1 | current_number = 0 |
使用 while 循环处理列表和字典
通过将 while 循环 同列表和字典结合起来使用,可收集、存储并组织大量输入,供以后查看和显示。
在列表之间移动元素
1 | # 首先,创建一个待验证用户列表 |
删除为特定值的所有列表元素
1 | pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat'] |
使用用户输入来填充字典
1 | responses = {} |
第八章 函数
定义函数
1 | def greet_user(): |
向函数传递信息
1 | def greet_user(username): |
形参和实参
形参(parameter),即函数完成工作所需的信息。
实参(argument),即调用函数时传递给函数的信息。
传递实参
可使用位置实参,这要求实参的顺序与形参的顺序相同;也可使用关键字实参,其中每个实参都由变量名和值组成;还可使用列表和字典。
位置实参
调用函数时,Python 必须将函数调用中的每个实参都关联到函数定义中的一个形参。为此, 最简单的关联方式是基于实参的顺序。这种关联方式称为位置实参。
1 | def describe_pet(animal_type, pet_name): |
关键字实参
关键字实参是传递给函数的名称值对。因为直接在实参中将名称和值关联起来,所以向函数传递实参时不会混淆。
1 | def describe_pet(animal_type, pet_name): |
默认值
编写函数时,可给每个形参指定默认值。在调用函数中给形参提供了实参时,Python 将使用指定的实参值;否则,将使用形参的默认值。
1 | def describe_pet(pet_name, animal_type='dog'): |
使用默认值时,必须先在形参列表中列出没有默认值的形参,再列出有默认值的实参。 这让 Python 依然能够正确地解读位置实参。
避免实参错误
实参多于或少于函数完成工作所需的信息时,将出现实参不匹配错误。
返回值
返回简单值
1 | def get_formatted_name(first_name, last_name): |
让实参变成可选的
可使用默认值来让实参变成可选的。
返回字典
函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。
1 | def build_person(first_name, last_name, age=None): |
为特殊值 None(表示变量没有值)
传递列表
1 | def greet_users(names): |
禁止函数修改列表
可向函数传递列表的副本而非原件。
切片表示法[:]创建列表的副本。
1 | function_name(list_name[:]) |
传递任意数量的实参
有时候,预先不知道函数需要接受多少个实参。
1 | def make_pizza(*toppings): |
形参名*toppings 中的星号让 Python 创建一个名为 toppings 的空元组,并将收到的所有值都封装到这个元组中。
结合使用位置实参和任意数量实参
如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。
1 | def make_pizza(size, *toppings): |
你经常会看到通用形参名*args,它也收集任意数量的位置实参。
使用任意数量的关键字实参
1 | def build_profile(first, last, **user_info): |
你经常会看到形参名**kwargs,它用于收集任意数量的关键字实参。
将函数存储在模块中
将函数存储在称为模块的独立文件中,再将模块导入到主程序中。
import
语句允许在当前运行的程序文件中使用模块中的代码。
导入整个模块
如果使用这种 import
语句导入了名为 module_name.py 的整个模块,就可 使用下面的语法来使用其中任何一个函数:
1 | module_name.function_name() |
导入特定的函数
还可以导入模块中的特定函数,这种导入方法的语法如下:
1 | from module_name import function_name |
通过用逗号分隔函数名,可根据需要从模块中导入任意数量的函数:
1 | from module_name import function_0, function_1, function_2 |
使用 as 给函数指定别名
如果要导入函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名。
指定别名的通用语法如下:
1 | from module_name import function_name as fn |
使用 as 给模块指定别名
给模块指定别名的通用语法如下:
1 | import module_name as mn |
导入模块中的所有函数
使用星号(*)运算符可让 Python 导入模块中的所有函数:
1 | from module_name import * |
Python 可能遇到多个名称相同的函数或变量,进而覆盖函数,而不是分别导入所有的函数
最佳的做法是,要么只导入需要使用的函数,要么导入整个模块并使用句点表示法。
第九章 类
创建和使用类
创建 Dog 类
1 | class Dog: |
类中的函数称为方法。
方法__init__是一个特殊方法,每当你根据 Dog 类创建 新实例时,Python 都会自动运行它。
务必确保__init__()的两边都 有两个下划线,否则当你使用类来创建实例时,将不会自动调用这个方法。
为何必须在方法定义中包含形参 self 呢?因 为 Python 调用这个方法来创建 Dog 实例时,将自动传入实参 self。每个与实例相关联的方法调用都自动传递实参 self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
根据类创建实例
1 | class Dog: |
使用类和实例
给属性指定默认值
创建实例时,有些属性无须通过形参来定义,可在方法__init__()中为其指定默认值。
修改属性的值
直接修改属性的值
最简单的方式是通过实例直接访问它。
通过方法修改属性的值
将值传递给方法, 由它在内部进行更新。
通过方法对属性的值进行递增
有时候需要将属性值递增特定的量,而不是将其设置为全新的值。
继承
一个类继承另一个类时,将自动获得另一个类的所有属性和方法。原有的类称为父类,而新类称为子类。子类继承了父类的所有属性和方法,同时还可以定义自己的属性和方法。
子类的方法__init__()
在既有类的基础上编写新类时,通常要调用父类的方法__init__()。这将初始化在父类 init()方法中定义的所有属性,从而让子类包含这些属性。
1 | class Car: |
super()是一个特殊函数,让你能够调用父类的方法。
给子类定义属性和方法
1 | class Car: |
重写父类的方法
可在子类中定义一个与要重写的父类方法同名的方法。这样,Python 将不会考虑这个父类方法,而只关注 你在子类中定义的相应方法。
将实例用作属性
有时候可能需要将类的一部分提取出来,作为一个独立的类。可以将大型类拆分成多个协同工作的小类。
1 | class Car: |
模拟实物
解决上述问题时,从较高的逻辑层面(而不是语法层面) 考虑;考虑的不是 Python,而是如何使用代码来表示实物
导入类
导入单个类
1 | from car import Car #import 语句让 Python 打开模块 car 并导入其中的 Car 类。 |
从一个模块中导入多个类
1 | from car import Car, ElectricCar |
从一个模块中导入多个类时,用逗号分隔了各个类
导入整个模块
还可以导入整个模块,再使用句点表示法访问需要的类。
1 | import car #导入了整个 car 模块 |
导入模块中的所有类
1 | from module_name import * |
不推荐使用这种导入方式,原因有二。
如果只看文件开头的 import 语句,就能清楚 地知道程序使用了哪些类,将大有裨益。然而这种导入方式没有明确地指出使用了模块中的哪些 类。
这种方式还可能引发名称方面的迷惑。如果不小心导入了一个与程序文件中其他东西同名的类,将引发难以诊断的错误。
需要从一个模块中导入很多类时,最好导入整个模块,并使用 module_name.ClassName 语法
来访问类。这样做时,虽然文件开头并没有列出用到的所有类,但你清楚地知道在程序的哪些地 方使用了导入的模块。这也避免了导入模块中的每个类可能引发的名称冲突。
使用别名
1 | from electric_car import ElectricCar as EC #可在 import 语句中给 ElectricCar 指定一个别名 |
类编码风格
类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。
对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的 功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也都应包含一个文档字符串, 对其中的类可用于做什么进行描述。
可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中, 可使用两个空行来分隔类。
需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的 import 语句, 再添加一个空行,然后编写导入你自己编写的模块的 import 语句。在包含多条 import 语句的程 序中,这种做法让人更容易明白程序使用的各个模块都来自何处。
第十章 文件和异常
从文件中读取数据
读取整个文件
1 | with open('pi_digits.txt',encoding='utf-8') as file_object: |
函数open()
接受一个参数:要打开的文件的名称。Python在当前执行的文件所在的目录中查找指定的文件。
函数open()
返 回一个表示文件的对象。在这里,open(‘pi_digits.txt’)返回一个表示文件pi_digits.txt 的对象, Python 将该对象赋给file_object 供以后使用。
关键字 with在不再需要访问文件后将其关闭。
我们调用了 open()
, 但没有调用 close()
。你只管打开文件,并在需要时使用它,Python 自会 在合适的时候自动将其关闭。
方法 read()
读取这个文件的全部内容,并将其作为一个长长的字符串赋给变量 contents。
文件路径
显示文件路径时,Windows 系统使用反斜杠(\)而不是斜杠(/),但在代码中依然可以使用斜杠。
如果在文件路径中直接使用反斜杠,将引发错误,因为反斜杠用于对字符串中的字符进行转义。例如,对于路径”C:\path\to\file.txt”,其中的\t 将被解读为制表符。如果一 定要使用反斜杠,可对路径中的每个反斜杠都进行转义,如”C:\\path\\to\\file.txt”。
逐行读取
要以每次一行的方式检查文件,可对文件对象使用 for 循环:
1 | filename = 'pi_digits.txt' |
关键字 with,让 Python 负 责妥善地打开和关闭文件。为查看文件的内容,通过对文件对象执行循环来遍历文件中的每一行
为何会出现这些空白行呢?因为在这个文件中,每行的末尾都有一个看不见的换行符,而函 数调用 print()也会加上一个换行符,因此每行末尾都有两个换行符:一个来自文件,另一个来 自函数调用 print()。要消除这些多余的空白行,可在函数调用 print()中使用 rstrip():
1 | filename = 'pi_digits.txt' |
创建一个包含文件各行内容的列表
使用关键字 with 时,open()返回的文件对象只在 with 代码块内可用。如果要在 with 代码块 外访问文件的内容,可在 with 代码块内将文件的各行存储在一个列表中。
1 | filename = 'pi_digits.txt' |
read() 每次读取整个文件,它通常将读取到底文件内容放到一个字符串变量中,也就是说 .read() 生成文件内容是一个字符串类型。
readline()每只读取文件的一行,通常也是读取到的一行内容放到一个字符串变量中,返回str类型。
readlines()每次按行读取整个文件内容,将读取到的内容放到一个列表中,返回list类型。(一行一行存起来)
写入文件
写入空文件
1 | filename = 'programming.txt' |
在本例中,调用 open()时提供了两个实参。第一个实参也是要打开的文件的名称。 第二个实参(’w’)告诉 Python,要以写入模式打开这个文件。打开文件时,可指定读取模式(’r’)、 写入模式(’w’)、附加模式(’a’)或读写模式(’r+’)。如果省略了模式实参,Python 将以默认的只读模式打开文件。
如果要写入的文件不存在,函数 open()将自动创建它。然而,以写入模式(’w’)打开文件 时千万要小心,因为如果指定的文件已经存在,Python 将在返回文件对象前清空该文件的内容。
Python 只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数 str()将其转换为字符串格式。
写入多行
函数 write()不会在写入的文本末尾添加换行符
1 | filename = 'programming.txt' |
附加到文件
如果要给文件添加内容,而不是覆盖原有的内容,可以以附加模式(‘a’)打开文件。
以附加模式打 开文件时,Python 不会在返回文件对象前清空文件的内容,而是将写入文件的行添加到文件末尾。 如果指定的文件不存在,Python 将为你创建一个空文件。
异常
Python 使用称为异常的特殊对象来管理程序执行期间发生的错误。每当发生让 Python 不知所措的错误时,它都会创建一个异常对象。
异常是使用 try-except 代码块处理的。使用 try-except 代码块时,即便出现异常,程序也将继续运行: 显示你编写的友好的错误消息,而不是令用户迷惑的 traceback。
使用 try-except 代码块
例如:
1 | try: |
使用异常避免崩溃
1 | print("Give me two numbers, and I'll divide them.") |
else 代码块
try-except-else 代码块的工作原理大致如下。Python 尝试执行 try 代码块中的代码,只有可能引发异常的代码才需要放在 try 语句中。有时候,有一些仅在 try 代码块成功执行时才需要运行的代码,这些代码应放在 else 代码块中。except 代码块告诉 Python,如果尝试运行 try 代 码块中的代码时引发了指定的异常该怎么办
处理 FileNotFoundError 异常
1 | filename = 'alice.txt' |
给参数 encoding 指定了值,在系统的默认编码与要读取文件使用的 编码不一致时,必须这样做。
分析文本
方法 split()
以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。
1 | filename = 'alice.txt' |
静默失败
要让程序静默失 败,可像通常那样编写 try 代码块,但在 except 代码块中明确地告诉 Python 什么都不要做。Python 有一个 pass 语句,可用于让 Python 在代码块中什么都不要做。
1 | def count_words(filename): |
pass 语句还充当了占位符,提醒你在程序的某个地方什么都没有做,并且以后也许要在这里做些什么。
存储数据
模块 json 让你能够将简单的 Python 数据结构转储到文件中,并在程序再次运行时加载该文 件中的数据。你还可以使用 json 在 Python 程序之间分享数据。
JSON(JavaScript Object Notation)格式最初是为 JavaScript 开发的,但随后成了一种常 见格式,被包括 Python 在内的众多语言采用。
使用 json.dump()和 json.load()
函数 json.dump()
接受两个实参:要存储的数据,以及可用于存储数据的文件对象。
1 | import json |
函数json.load()
将列表读取到内存中:
1 | import json |
保存和读取用户生成的数据
1 | import json |
重构
代码能够正确地运行,但通过将其划分为一系列完成具体工作的 函数,还可以改进。这样的过程称为重构。
1 | import json |
每个函数都执行单一而清晰的任务。
要编写出清晰而易于 维护和扩展的代码,这种划分必不可少。
第十一章 测试代码
测试函数
可通过的测试
下面的测试用例只包含一个方法,它检查函数 get_formatted_name()在给定名和姓时能否正确工作:
1 | import unittest |
创建了一个名 为 NamesTestCase 的类,用于包含一系列针对 get_formatted_name()的单元测试。这个类必须继承 unittest.TestCase 类,这样 Python 才知道如何运行你编写的测试。
运行 test_name_function.py 时,所有以 test_打头的方法都将自动运行。
断言方法核实得到的结果是否 与期望的结果一致。
很多测试框架都会先导入测试文件再运行。导入文件时,解释器将在导入的同时执行它。if 代码块检查特殊变量__name__,这个变量是在程序执行时设置的。如果这个文件作为主程序执行,变量__name__将被设置为’__main__‘。在这里,调用 unittest.main()来运行测试用例。如果这个文件被测试框架导入,变量的值将不是’__main__‘,因此不会调用 unittest.main()。
测试类
各种断言方法
setUp()方法
setUp()让我们只需创建这些对象 一次,就能在每个测试方法中使用。
测试自己编写的类时,方法 setUp()让测试方法编写起来更容易:可在 setUp()方法中创建一 系列实例并设置其属性,再在测试方法中直接使用这些实例。相比于在每个测试方法中都创建实 例并设置其属性,这要容易得多。