字符串
-
字符串可以使用单引号或双引号括起来
'This is a string'
"This is also a string" -
拼接字符串
message = "Hello, " + full_name.title() + "!" -
title()方法
以首字母大写的方式显示每个单词,即将每个单词的首字母都改为大写 -
删除空白
空白泛指任何非打印字符,如空格、制表符和换行符,如: \t代表制表符,\n代表换行符。
lstrip()、rstrip()、strip()分别删除左边空白、删除右边空白、删除左右空白 -
字符串中使用变量
first_name = "ada"
last_name = "lovelace"
full_name = f"{first_name} {last_name}"
print(full_name)
print(f"Hello, {full_name.title()}!")
这种字符串称为 f 字符串。f 是 format(设置格式)的简写,因为 Python 通
过把花括号内的变量替换为其值来设置字符串的格式
-
print
在Python 2中,无需将要打印的内容放在括号内,如:print "Hello Python 2.7 world!"
Python 3中的print是一个函数,因此括号必不可少。 -
删除前缀removeprefix()
>>> nostarch_url = 'https://nostarch.com'
>>> nostarch_url.removeprefix('https://')
'nostarch.com'
- 删除后缀removesuffix()
数
整数
- 乘方(**)
>>> 3 ** 2
9
浮点数
Python 将带⼩数点的数称为浮点数。
在 Python 中,⽆论是哪种运算,只要有操作数是浮点数,默认得到的就总
是浮点数,即便结果原本为整数
- 将任意两个数相除,结果总是浮点数,即便这两个数都是整数且能整除
>>> 4/2
2.0
- 在其他任何运算中,如果⼀个操作数是整数,另⼀个操作数是浮点数,结
果也总是浮点数
>>> 1 + 2.0
3.0
>>> 2 * 3.0
6.0
>>> 3.0 ** 2
9.0
其它
- 数中的下划线
在书写很⼤的数时,可使⽤下划线将其中的位分组,使其更清晰易读。
在存储这种数时,Python 会忽略其中的下划线。在对数字位分组时,即便不是将每三位分成⼀组,也不会影响最终的值。
在 Python 看来,1000 与 1_000 没什么不同,1_000 与 10_00 也没什么不同。
这种表⽰法既适⽤于整数,也适⽤于浮点数。
>>> universe_age = 14_000_000_000
>>> print(universe_age)
14000000000
- 同时给多个变量赋值
>>> x, y, z = 0, 0, 0
- 常量
Python 没有内置的常量类型,但 Python 程序员会使⽤全⼤写字⺟来指出应将某个变量视为常量,其值应始终不变。
注释
-
单行注释
单行注释以 # 开头 -
多行注释
多行注释用三个单引号 ''' 或者三个双引号 """ 将注释括起来
列表
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles)
print(bicycles[0])
- 索引从 0 ⽽不是 1 开始
- 修改列表元素
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
motorcycles[0] = 'ducati'
print(motorcycles)
- 在列表中添加元素
在列表末尾添加元素:
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
motorcycles.append('ducati')
print(motorcycles)
motorcycles = []
motorcycles.append('honda')
motorcycles.append('yamaha')
motorcycles.append('suzuki')
print(motorcycles)
在列表中插⼊元素:
motorcycles = ['honda', 'yamaha', 'suzuki']
motorcycles.insert(0, 'ducati')
print(motorcycles)
- 从列表中删除元素
使⽤ del 语句删除元素:
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
del motorcycles[0]
print(motorcycles)
使⽤ pop() ⽅法删除元素:
pop() ⽅法删除列表末尾的元素,并让你能够接着使⽤它
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
popped_motorcycle = motorcycles.pop()
print(motorcycles)
print(popped_motorcycle)
删除列表中任意位置的元素:
motorcycles = ['honda', 'yamaha', 'suzuki']
first_owned = motorcycles.pop(0)
print(f"The first motorcycle I owned was a {first_owned.title()}.")
根据值删除元素:
motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati']
print(motorcycles)
motorcycles.remove('ducati')
print(motorcycles)
remove() ⽅法只删除第⼀个指定的值。如果要删除的值可能在列表中出现多次,就需要使⽤循环,确保将每个值都删
除。
- 管理列表
使⽤ sort() ⽅法对列表进⾏永久排序
cars = ['bmw', 'audi', 'toyota', 'subaru']
cars.sort()
#还可以按与字⺟顺序相反的顺序排列列表元素
cars.sort(reverse=True)
print(cars)
使⽤ sorted() 函数对列表进⾏临时排序:
在调⽤ sorted() 函数后,列表元素的排列顺序并没有变。如果要按与字⺟顺序相反的顺序显⽰列表,也可向 sorted() 函数传递参数 reverse=True
cars = ['bmw', 'audi', 'toyota', 'subaru']
print("Here is the original list:")
print(cars)
print("\nHere is the sorted list:")
print(sorted(cars))
print("\nHere is the original list again:")
print(cars)
反向打印列表:
要反转列表元素的排列顺序,可使⽤ reverse() ⽅法。
reverse() ⽅法会永久地修改列表元素的排列顺序,但可随时恢复到原来的排列顺序,只需对列表再次调⽤ reverse() 即可
cars = ['bmw', 'audi', 'toyota', 'subaru']
print(cars)
cars.reverse()
print(cars)
确定列表的⻓度:
使⽤ len() 函数可快速获悉列表的⻓度。
>>> cars = ['bmw', 'audi', 'toyota', 'subaru']
>>> len(cars)
- 操作列表
遍历整个列表:
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician)
- 创建数值列表
使⽤ range() 函数:
for value in range(1, 5):
print(value)
range() 函数让 Python 从指定的第⼀个值开始数,并在到达指定的第⼆个值时停⽌,因此输出不包含第⼆个值(这⾥为 5)。
在调⽤ range() 函数时,也可只指定⼀个参数,这样它将从 0 开始,例
如,range(6) 返回数 0〜5(含)。
在使⽤ range() 函数时,还可指定步⻓。为此,可以给这个函数指定第三个参数,Python 将根据这个步⻓来⽣成数
even_numbers = list(range(2, 11, 2))
print(even_numbers)
使⽤ range() 创建数值列表:
numbers = list(range(1, 6))
print(numbers)
要创建数值列表,可使⽤ list() 函数将 range() 的结果直接转换为列表
对数值列表执⾏简单的统计计算:
>>> digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> min(digits)
>>> max(digits)
>>> sum(digits)
列表推导式:
将 for 循环和创建新元素的代码合并成⼀⾏,并⾃动追加新元素
squares = [value**2 for value in range(1, 11)]
print(squares)
- 使⽤列表的⼀部分
切⽚:
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[0:3])
如果没有指定第⼀个索引,Python 将⾃动从列表开头开始。
要让切⽚终⽌于列表末尾,也可使⽤类似的语法。
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[:4])
print(players[2:])
print(players[1:5:2])
可在表⽰切⽚的⽅括号内指定第三个值。这个值告诉 Python 在指定范围内每隔多少元素提取⼀个
复制列表:
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]
print("My favorite foods are:")
print(my_foods)
print("\nMy friend's favorite foods are:")
print(friend_foods)
如果通过friend_foods = my_foods,不能得到两个列表,对其中的一个进行修改会反应到另一个列表
元组
Python将不能修改的值称为不可变的,⽽不可变的列表称为元组(tuple)
dimensions = (200, 50)
print(dimensions[0])
print(dimensions[1])
如果你要定义只包含⼀个元素的元组,必须在这个元素后⾯加上逗号。
my_t = (3,)
遍历元组中的所有值:
dimensions = (200, 50)
for dimension in dimensions:
print(dimension)
修改元组变量
dimensions = (200, 50)
print("Original dimensions:")
for dimension in dimensions:
print(dimension)
dimensions = (400, 100)
print("\nModified dimensions:")
for dimension in dimensions:
print(dimension)
if语句
- 检查是否相等,==
- 检查是否不等,!=
- 检查多个条件,and,or
- 检查特定的值是否在列表中,in
>>> requested_toppings = ['mushrooms', 'onions', 'pineapple']
>>> 'mushrooms' in requested_toppings
True
>>> 'pepperoni' in requested_toppings
False
- 检查特定的值是否不在列表中,not in
- 布尔表达式,True,False
- if,if-else,if elif else
Python 并不要求 if-elif 结构后⾯必须有 else 代码块。在⼀些情况下,else 代码块很有⽤;⽽在其他情况下,使⽤⼀条 elif 语句来处理特定的情形更清晰
age = 12
if age < 4:
price = 0
elif age < 18:
price = 25
elif age < 65:
price = 40
elif age >= 65:
price = 20
print(f"Your admission cost is ${price}.")
- 确定列表⾮空
requested_toppings = []
if requested_toppings:
for requested_topping in requested_toppings:
print(f"Adding {requested_topping}.")
print("\nFinished making your pizza!")
else:
print("Are you sure you want a plain pizza?")
对于数值 0、空值 None、单引号空字符串 ''、双引号空字符串 ""、空列表 []、空元组 ()、空字典 {},Python 都会返回 False
字典
- 使用字典
在 Python 中,字典(dictionary)是⼀系列键值对。每个键都与⼀个值关
联,可以使⽤键来访问与之关联的值。与键相关联的值可以是数、字符
串、列表乃⾄字典。事实上,可将任意 Python 对象⽤作字典中的值
alien_0 = {'color': 'green', 'points': 5}
print(alien_0['color'])
print(alien_0['points'])
- 添加键值对
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0)
- 创建⼀个空字典
alien_0 = {}
alien_0['color'] = 'green'
alien_0['points'] = 5
print(alien_0)
- 修改字典中的值
alien_0 = {'color': 'green'}
print(f"The alien is {alien_0['color']}.")
alien_0['color'] = 'yellow'
print(f"The alien is now {alien_0['color']}.")
- 删除键值对
对于字典中不再需要的信息,可使⽤ del 语句将相应的键值对彻底删除。
在使⽤ del 语句时,必须指定字典名和要删除的键
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
del alien_0['points']
print(alien_0)
- 使⽤ get() 来访问值
可使⽤ get() ⽅法在指定的键不存在时返回⼀个默认值。get() ⽅法的第⼀个参数⽤于指定键,是必不可少的;第⼆个参数为当指定的键不存在时要返回的值,是可选的。
在调⽤ get() 时,如果没有指定第⼆个参数且指定的键不存在,Python 将返回值 None,这个特殊的值表⽰没有相应的值。这并⾮错误,None 只是⼀个表⽰所需值不存在的特殊值。 - 遍历字典
字典可⽤于以各种⽅式存储信息,因此有多种遍历⽅式:既可遍历字典的所有键值对,也可只遍历键或值。
遍历所有的键值对:
user_0 = {
'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
for key, value in user_0.items():
print(f"\nKey: {key}")
print(f"Value: {value}")
遍历字典中的所有键:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'rust',
'phil': 'python',
}
for name in favorite_languages.keys():
print(name.title())
for name in favorite_languages:
在遍历字典时,会默认遍历所有的键
favorite_languages = {
--snip--
}
if 'erin' not in favorite_languages.keys():
print("Erin, please take our poll!")
遍历字典中的所有值:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'rust',
'phil': 'python',
}
print("The following languages have been mentioned:")
for language in favorite_languages.values():
print(language.title())
排列键列表的副本:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'rust',
'phil': 'python',
}
for name in sorted(favorite_languages.keys()):
print(f"{name.title()}, thank you for taking the poll.")
集合(set)剔除重复项:
favorite_languages = {
--snip--
}
print("The following languages have been mentioned:")
for language in set(favorite_languages.values()):
print(language.title())
可以使⽤⼀对花括号直接创建集合,并在其中⽤逗号分隔元素:
>>> languages = {'python', 'rust', 'python', 'c'}
>>> languages
{'rust', 'python', 'c'}
集合和字典很容易混淆,因为它们都是⽤⼀对花括号定义的。当花括号内没有键值对时,定义的很可能是集合。不同于列表和字典,集合不会以特定的顺序存储元素。
- 嵌套
有时候,需要将多个字典存储在列表中或将列表作为值存储在字典中,这称为嵌套。可以在列表中嵌套字典,在字典中嵌套列表,甚⾄在字典中嵌套字典。
字典列表:
alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
aliens = [alien_0, alien_1, alien_2]
for alien in aliens:
print(alien)
在字典中存储列表:
# 存储顾客所点⽐萨的信息
pizza = {
'crust': 'thick',
'toppings': ['mushrooms', 'extra cheese'],
}
# 概述顾客点的⽐萨
print(f"You ordered a {pizza['crust']}-crust pizza "
"with the following toppings:")
for topping in pizza['toppings']:
print(f"\t{topping}")
在字典中存储字典:
# 存储顾客所点⽐萨的信息
pizza = {
'crust': 'thick',
'toppings': ['mushrooms', 'extra cheese'],
}
# 概述顾客点的⽐萨
print(f"You ordered a {pizza['crust']}-crust pizza "
"with the following toppings:")
for topping in pizza['toppings']:
print(f"\t{topping}")
while 循环
current_number = 1
while current_number <= 5:
print(current_number)
current_number += 1
-
使⽤ break 退出循环
如果不管条件测试的结果如何,想⽴即退出 while 循环,不再运⾏循环中余下的代码,可使⽤ break 语句 -
在循环中使⽤ continue
要返回循环开头,并根据条件测试的结果决定是否继续执⾏循环,可使⽤
continue 语句,它不像 break 语句那样不再执⾏余下的代码并退出整个循环 -
删除为特定值的所有列表元素
pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)
while 'cat' in pets:
pets.remove('cat')
print(pets)
函数
def greet_user(username):
"""显⽰简单的问候语"""
print(f"Hello, {username.title()}!")
greet_user('jesse')
-
形参
在 greet_user() 函数的定义中,变量 username 是⼀个形参 -
实参
即在调⽤函数时传递给函数的信息 -
传递实参
函数定义中可能包含多个形参,因此函数调⽤中也可能包含多个实参。向
函数传递实参的⽅式很多:既可以使⽤位置实参,这要求实参的顺序与形
参的顺序相同;也可以使⽤关键字实参,其中每个实参都由变量名和值组
成;还可以使⽤列表和字典。
位置实参:
def describe_pet(animal_type, pet_name):
"""显⽰宠物的信息"""
print(f"\nI have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet('hamster', 'harry')
关键字实参:
关键字实参是传递给函数的名值对
def describe_pet(animal_type, pet_name):
"""显⽰宠物的信息"""
print(f"\nI have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet(animal_type='hamster', pet_name='harry')
关键字实参的顺序⽆关紧要,因为 Python 知道各个值该被赋给哪个形参。
下⾯两个函数调⽤是等效的:
describe_pet(animal_type='hamster', pet_name='harry')
describe_pet(pet_name='harry', animal_type='hamster')
- 默认值
def describe_pet(pet_name, animal_type='dog'):
"""显⽰宠物的信息"""
print(f"\nI have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet(pet_name='willie')
当使⽤默认值时,必须在形参列表中先列出没有默认值的形参,再列出有默认值的形参。这让 Python 依然能够正确地解读位置实参。
-
在函数中修改列表
将列表传递给函数后,函数就可以对其进⾏修改了 -
禁⽌函数修改列表
print_models(unprinted_designs[:], completed_models)
- 传递任意数量的实参
有时候,你预先不知道函数需要接受多少个实参,好在 Python 允许函数从调⽤语句中收集任意数量的实参
def make_pizza(*toppings):
"""打印顾客点的所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
形参名 *toppings 中的星号让 Python 创建⼀个名为 toppings 的元组,该元组包含函数收到的所有值
- 使⽤任意数量的关键字实参
def build_profile(first, last, **user_info):
"""创建⼀个字典,其中包含我们知道的有关⽤户的⼀切"""
user_info['first_name'] = first
user_info['last_name'] = last
return user_info
user_profile = build_profile('albert', 'einstein',
location='princeton',
field='physics')
print(user_profile)
形参 **user_info 中的两个星号让 Python 创建⼀个名为 user_info 的字典,该字典包含函数收到的其他所有名值对。
你经常会看到形参名 **kwargs,它⽤于收集任意数量的关键字实参。
- 将函数存储在模块中
将函数存储在称为模块的独⽴⽂件中,再将模块导⼊(import)主程序。
导⼊整个模块:
只需编写⼀条 import 语句并在其中指定模块名,就可在程序中使⽤该模块中的所有函数
import module_name
module_name.function_name()
导⼊特定的函数:
from module_name import function_name
from module_name import function_0, function_1, function_2
from pizza import make_pizza
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
使⽤ as 给函数指定别名:
如果要导⼊的函数的名称太⻓或者可能与程序中既有的名称冲突,可指定简短⽽独⼀⽆⼆的别名(alias):函数的另⼀个名称,类似于外号。要给函数指定这种特殊的外号,需要在导⼊时这样做。
from module_name import function_name as fn
from pizza import make_pizza as mp
mp(16, 'pepperoni')
mp(12, 'mushrooms', 'green peppers', 'extra cheese')
使⽤ as 给模块指定别名:
import pizza as p
p.make_pizza(16, 'pepperoni')
p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
导⼊模块中的所有函数:
from pizza import *
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
类
class Dog:
"""⼀次模拟⼩狗的简单尝试"""
def __init__(self, name, age):
"""初始化属性 name 和 age"""
self.name = name
self.age = age
def sit(self):
"""模拟⼩狗收到命令时坐下"""
print(f"{self.name} is now sitting.")
def roll_over(self):
"""模拟⼩狗收到命令时打滚"""
print(f"{self.name} rolled over!")
my_dog = Dog('Willie', 6)
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")
__init__()
⽅法
是⼀个特殊⽅法,每当你根据 Dog 类创建新实例时,Python 都会⾃动运⾏
它。在这个⽅法的名称中,开头和末尾各有两个下划线,这是⼀种约定,
旨在避免 Python 默认⽅法与普通⽅法发⽣名称冲突。
修改属性:
- 直接修改属性的值
- 通过方法修改属性的值
继承:
class Car:
"""⼀次模拟汽⻋的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽⻋的属性"""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
def get_descriptive_name(self):
"""返回格式规范的描述性名称"""
long_name = f"{self.year} {self.make} {self.model}"
return long_name.title()
def read_odometer(self):
"""打印⼀个句⼦,指出汽⻋的⾏驶⾥程"""
print(f"This car has {self.odometer_reading} miles on it.")
def update_odometer(self, mileage):
"""将⾥程表读数设置为给定的值"""
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
def increment_odometer(self, miles):
"""让⾥程表读数增加给定的量"""
self.odometer_reading += miles
class ElectricCar(Car):
"""电动汽⻋的独特之处"""
def __init__(self, make, model, year):
"""初始化⽗类的属性"""
super().__init__(make, model, year)
my_leaf = ElectricCar('nissan', 'leaf', 2024)
print(my_leaf.get_descriptive_name())
在既有的类的基础上编写新类,通常要调⽤⽗类的 init() ⽅法。这
将初始化在⽗类的 init() ⽅法中定义的所有属性,从⽽让⼦类也可
以使⽤这些属性。
在创建⼦类时,⽗类必须包含在当前⽂件中,且位于⼦类前⾯。
从⼀个模块中导⼊一个或多个类:
from car import ElectricCar
from car import Car, ElectricCar
导⼊整个模块,再使⽤点号访问需要的类
import car
my_mustang = car.Car('ford', 'mustang', 2024)
print(my_mustang.get_descriptive_name())
导⼊模块中的所有类(不推荐这种导⼊⽅式)
from module_name import *
给类或模块使⽤别名:
from electric_car import ElectricCar as EC
import electric_car as ec
类名应采⽤驼峰命名法,即将类名中的每个单词的⾸字⺟都⼤写,并且不
使⽤下划线。实例名和模块名都采⽤全⼩写格式,并在单词之间加上下划
线。
可以使⽤空⾏来组织代码,但不宜过多。在类中,可以使⽤⼀个空⾏来分
隔⽅法;⽽在模块中,可以使⽤两个空⾏来分隔类。
当需要同时导⼊标准库中的模块和你编写的模块时,先编写导⼊标准库模
块的 import 语句,再添加⼀个空⾏,然后编写导⼊你⾃⼰编写的模块的
import 语句。
文件和异常
from pathlib import Path
path = Path('pi_digits.txt')
contents = path.read_text()
contents = contents.rstrip()
print(contents)
你可以使⽤ splitlines() ⽅法将冗⻓的字符串转换为⼀系列⾏
lines = contents.splitlines()
写入文件:
from pathlib import Path
path = Path('programming.txt')
path.write_text("I love programming.")
在读取⽂本⽂件时,Python 将其中的所有⽂本都解释为字符串。如果读取的是数,并且要将其作为数值使⽤,就必须使⽤ int()函数将其转换为整数,或者使⽤ float() 函数将其转换为浮点数。
Python 只能将字符串写⼊⽂本⽂件。如果要将数值数据存储到
⽂本⽂件中,必须先使⽤函数 str() 将其转换为字符串格式
异常:
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
通过将可能引发错误的代码放在 try-except 代码块中,可提⾼程序抵御
错误的能⼒。因为错误是执⾏除法运算的代码⾏导致的,所以需要将它放
到 try-except 代码块中。这个⽰例还包含⼀个 else 代码块,只有 try
代码块成功执⾏才需要继续执⾏的代码,都应放到 else 代码块中。
while True:
--snip--
if second_number == 'q':
break
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by 0!")
else:
print(answer)
要让程序静默失败,可像通常那样编写 try 代码块,但在 except 代码块中明确地告诉 Python 什么都不要做。Python 有⼀个 pass 语句,可在代码块中使⽤它来让 Python 什么都不做。
def count_words(path):
"""计算⼀个⽂件⼤致包含多少个单词"""
try:
--snip--
except FileNotFoundError:
pass
else:
--snip--
json.dumps() 系列化:
from pathlib import Path
import json
numbers = [2, 3, 5, 7, 11, 13]
path = Path('numbers.json')
contents = json.dumps(numbers)
path.write_text(contents)
json.loads 反序列化:
from pathlib import Path
import json
path = Path('numbers.json')
contents = path.read_text()
numbers = json.loads(contents)
print(numbers)
测试
# 更新系统中安装的任何包
python -m pip install --upgrade package_name
# 命令安装众多的第三⽅包
# --user,这个标志让 Python 只为当前⽤户安装指定的包
python -m pip install --user package_name
# 将 pip 升级到最新版本
python.exe -m pip install --upgrade pip
# 安装 pytest
python -m pip install --user pytest
测试⽂件的名称很重要,必须以test_打头。当你让 pytest 运⾏测试时,它将查找以 test_打头的⽂件,并运⾏其中的所有测试。
测试函数必须以 test_ 打头。在测试过程中,pytest 将找出并运⾏所有以 test_ 打头的函数。
如果在执⾏命令 pytest 时没有指定任何参数,pytest 将运⾏它在当前⽬录中找到的所有测试。为了专注于⼀个测试⽂件,可将该测试⽂件的名称作为参数传递给 pytest。
pytest
pytest test_survey.py
常用的断言语句:
- assert a == b 断⾔两个值相等
- assert a != b 断⾔两个值不等
- assert a 断⾔ a 的布尔求值为 True
- assert not a 断⾔ a 的布尔求值为 False
- assert element in list 断⾔元素在列表中
- assert element not in list 断⾔元素不在列表中
测试类
夹具(fixture):
在测试中,夹具(fixture)可帮助我们搭建测试环境。这通常意味着创建供
多个测试使⽤的资源。在 pytest 中,要创建夹具,可编写⼀个使⽤装饰器 @pytest.fixture 装饰的函数。装饰器(decorator)是放在函数定义前⾯的指令。在运⾏函数前,Python 将该指令应⽤于函数,以修改函数代码的⾏为。
import pytest
from survey import AnonymousSurvey
@pytest.fixture
def language_survey():
"""⼀个可供所有测试函数使⽤的 AnonymousSurvey 实例"""
question = "What language did you first learn to speak?"
language_survey = AnonymousSurvey(question)
return language_survey
def test_store_single_response(language_survey):
"""测试单个答案会被妥善地存储"""
language_survey.store_response('English')
assert 'English' in language_survey.responses
def test_store_three_responses(language_survey):
"""测试三个答案会被妥善地存储"""
responses = ['English', 'Spanish', 'Mandarin']
for response in responses:
language_survey.store_response(response)
for response in responses:
assert response in language_survey.responses
当测试函数的⼀个形参与应⽤了装饰器@pytest.fixture 的函数(夹具)同名时,将⾃动运⾏夹具,并将夹具返回的值传递给测试函数。
网友评论