第一章 变量和简单的数据类型

1.1 字符串

  1. 修改字符串的大小写
1
2
3
变量名.title( ) # 首字母大写,其他为小写
变量名.lower( ) # 全部小写
变量名.upper() # 全大写
  1. 字符串的拼接
1
f"字符串 {变量名} {变量名}"
  1. 删除空白
1
2
3
变量名.rstrip() # 删除右侧空白
变量名.lstrip() # 删除左侧空白
变量名.strip() # 删除两侧空白
  1. 删除前缀
1
变量名.removeprefix(前缀)

1.2 数

  1. 数中的下划线
1
universe_age=14_000_000 # 14000000
  1. 同时给多个变量赋值
1
a,b=10,20

第二章 列表简介

2.1 修改、添加和删除元素

  1. 修改
    1
    列表名[索引] = 元素
  2. 添加
    1
    2
    3
    列表名.append(元素) # 添加到列表末尾
    列表名.insert(索引,元素) # 在指定位置添加元素
    列表名 += [元素1,元素2] # 添加多个元素
  3. 删除
    1
    2
    3
    del 列表名[索引] # 删除指定位置元素
    列表名.pop(索引) # 删除指定位置元素,并返回被删除的元素
    列表名.remove(元素) # 删除第一个出现的指定元素

2.2 管理列表

  1. 使用sort()方法对列表进行永久排序
    1
    2
    列表名.sort( ) # 按字母顺序从小到大排序
    列表名.sort(reverse=True) # 按字母顺序从大到小排序
  2. 使用sorted()函数对列表进行临时排序
    1
    sorted(列表名) # 按字母顺序从小到大排序
  3. 列表反转
    1
    列表名.reverse()
  4. 确定指定元素的个数、列表长度
    1
    2
    列表名.count(元素) # 返回指定元素的个数
    len(列表名) # 返回列表长度

第三章 操作列表

3.1 遍历整个列表

  1. 遍历列表
    1
    2
    for 变量名 in 列表名:
    print(变量名)

3.2创建数值列表

  1. 使用range( )函数
    1
    2
    3
    # 创建1-5的列表
    for value in range(1,5):
    print(value)
  2. 使用range()创建数值列表
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     numbers = list(range(1,6))
    print(numbers)
    # range()函数还可以指定步长
    even_numbers = list(range(1,6,2)) # 从1开始,到5结止,步长为2
    print(even_numbers)
    # 创建一个列表,包含前10个整数的平方
    squares = []
    for value in range(1, 10):
    squares.append(value ** 2)
    print(squares)
  3. 对数值列表执行简单的统计计算
    1
    2
    digits = [1,2,3,4,5,6,7,8,9]
    print(min(digits), max(digits), sum(digits))
  4. 列表推导式
    1
    2
    3
    4
    5
    6
    7
    列表名 = [表达式 for 变量 in 列表名 if 条件]
    # 例子:生成一列数字的平方
    squares = [x**2 for x in range(1, 10)]
    print(squares)
    # 例子:生成所包含数字的平方和大于100的数字的列表
    greater_than_100 = [x for x in range(1, 20) if x**2 > 100]
    print(greater_than_100)

3.3 使用列表的一部分

  1. 切片
    1
    2
    3
    4
    5
    6
    7
    players = ['charles','martina','michael','florence','eli']
    print(players[0:3]) # 0 to 2
    print(players[1:4]) # 1 to 3
    print(players[:4]) # 0 to 3
    print(players[2:]) # 2 to end
    print(players[-3:]) #last 3
    print(players[1:4:2]) # 1 to 3, every other one
  2. 遍历切片
    1
    2
    3
    4
    players = ['charles','martina','michael','florence','eli']
    print("Here are the first three aplayers on my team:")
    for player in players[:3]:
    print(player.title())
  3. 复制列表

复制列表时,只是创建了新列表的引用,而不是创建副本

1
2
3
4
my_food = ['pizza','falafel', 'carrot coke']
friend_food = my_food[:]
print(my_food)
print(friend_food)

3.4元组

元组是不能修改元素的列表,但可以重新赋值

第四章 if语句

4.1 if语句

  1. 简单的if语句
    1
    2
    if 条件:
    代码块
  2. if-else语句
    1
    2
    3
    4
    if 条件1:
    代码块1
    elif 条件2:
    代码块2
  3. if-elif-else语句
    1
    2
    3
    4
    5
    6
    if 条件1:
    代码块1
    elif 条件2:
    代码块2
    else:
    代码块3
  4. 使用多个elif代码块
    1
    2
    3
    4
    5
    6
    7
    8
     if 条件1:
    代码块1
    elif 条件2:
    代码块2
    elif 条件3:
    代码块3
    else:
    代码块4

4.2 使用if语句处理列表

  1. 检查特殊元素

    1
    2
    3
    4
    5
    6
    7
    8
    request_toppings = ['mushrooms', 'green peppers', 'extra cheese']

    for request_topping in request_toppings:
    if request_topping == 'green peppers':
    print("Sorry,we are out of green peppers right now.")
    else:
    print(f"Adding {request_topping}.")
    print("\nFinished making your pizza!")
  2. 确定列表为空

    1
    2
    3
    4
    5
    6
    7
    8
    request_toppings = []

    if request_toppings:
    for request_topping in request_toppings:
    print(f"Adding {request_topping}.")
    print(f"\nFinished making your pizza!")
    else:
    print("Are you sure you want a plain pizza?")

列表为空时返回False,不为空时返回True

  1. 使用多个列表
1
2
3
4
5
6
7
8
9
10
# 列表一包含店内供应的配料,列表二包含顾客的请求,检查顾客的请求是否在店内供应的配料中,再决定是否在比萨中添加它。
available_toppings = ['mushrooms', 'olives', 'green peppers', 'pepperoni', 'pineapple', 'extra cheese']
request_toppings = ['mushrooms', 'french fires', 'extra cheese']
for request_topping in request_toppings:
if request_topping in available_toppings:
print(f"Adding {request_topping}.")
else :
print(f"Sorry, we don't have {request_topping}.")

print("\nFinished making your pizza!")

第五章 字典

5.1 一个简单的字典

  1. 创建字典
1
2
3
4
alien_0 = {'color': 'green', 'points': 5}

print(alien_0['color']) # 访问字典中的值
print(alien_0['points'])

5.2 使用字典

字典是一系列键值对,每个键都与一个值关联,可以使用键来访问与之关联的值。

与键相关联的值的类型可以是数字、字符串、列表乃至字典。

  1. 访问字典中的值

[]中放置的是键,而不是索引。

1
2
3
4
alien_0 = {'color': 'green', 'points': 5}

new_points = alien_0['points']
print(f"You just earned {new_points} points!")
  1. 添加键值对
1
2
3
4
5
6
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)

alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0)
  1. 从创建一个空字典开始
1
2
3
4
alien_0 = {}
alien_0['color'] = 'green'
alien_0['points'] = 5
print(alien_0)
  1. 修改字典中的值
1
2
3
4
5
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']}")
  1. 删除键值对

del语句可以删除字典中的键值对,也可以使用pop()方法删除键值对

1
2
3
4
5
alien_0 = {'color':'green','points':5}
print(alien_0)

del alien_0['points']
print(alien_0)
  1. 由类似的对象组成字典
1
2
3
4
5
6
7
8
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'rust',
'phil': 'python',
}
languages = favorite_languages['sarah'].title()
print(f"Sarah's favorite language is {languages}")
  1. 使用get()来访问值

get()方法返回与键相关联的值,如果字典中没有指定的键,则返回None或指定值。

1
2
3
alien_0 = {'color': 'green', 'speed': 'slow'}
point_value = alien_0.get('points', 'No point value assigned.')
print(point_value)

5.3 遍历字典

  1. 遍历所有的键值对

items()方法返回一个包含字典中所有键值对的列表,每个键值对用两个元素表示。

1
2
3
4
5
6
7
8
user_0 = {
'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
for key,value in user_0.items():
print(f"\nKey: {key}")
print(f"Value: {value}")
  1. 遍历字典所有的键

keys()方法返回一个包含字典中所有键的列表。

1
2
3
4
5
6
7
8
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
for name in favorite_languages.keys():
print(name.title())
  1. 按特定的顺序遍历字典中的所有键

使用sorted()函数来获得按特定顺序排列的键列表的副本

1
2
3
4
5
6
7
8
9
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 poil.")
  1. 遍历字典中的所有值

values()方法返回一个包含字典中所有值的列表。

1
2
3
4
5
6
7
8
9
10
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())

剔除重复项,可使用集合(set) 。集合中的每个元素都必须是独一无二的。

1
2
3
4
5
6
7
8
9
10
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'rust',
'phil': 'python',
}

print("The following languages have been mentioned:")
for language in set(favorite_languages.values()):
print(language.title())

可以使用一对花括号直接创建集合(不重复的元素),并在其中用逗号分隔元素:

1
2
languages = {'python', 'rust', 'python', 'c'}
print(languages)

集合和字典很容易混淆,因为它们都是一对花括号定义的。当花括号没有键值对时,定义的很可能是集合。不同于列表和字典,集合不会以特定的顺序存储元素。

5.4 嵌套

  1. 字典列表
1
2
3
4
5
6
7
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)
1
2
3
4
5
6
7
8
9
aliens = []
for alien_number in range(30):
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(new_alien)
for alien in aliens[:5]:
print(alien)
print("```")

print(f"Total number of aliens: {len(aliens)}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
aliens = []
for alien_number in range(30):
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(new_alien)
for alien in aliens[:5]:
print(alien)
print("```")

print(f"Total number of aliens: {len(aliens)}")

for alien in aliens[:3]:
if alien['color'] == 'green':
alien['color'] = 'yellow'
alien['speed'] = 'medium'
alien['points'] = 10

for alien in aliens[:5]:
print(alien)
  1. 在字典中存储列表
1
2
3
4
5
6
7
8
9
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}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
favorite_languages = {
'jen': ['python','rust'],
'sarah': ['c'],
'edward': ['rust','c'],
'phil': ['python', 'haskell'],
}

for name,languages in favorite_languages.items():
if len(languages)!=1:
print(f"\n{name.title()}'s favorite languages are:")
for language in languages:
print(f"\t{language.title()}")
else:
print(f"\n{name.title()}'s favorite language is:")
for language in languages:
print(f"\t{language.title()}")
  1. 在字典中存储字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
users = {
'aeinstein':{
'first':'albert',
'last':'einstein',
'location':'princeton',
},
'mcurie':{
'first':'marie',
'last':'curie',
'location':'paris',
},
}

for username,user_info in users.items():
print(f"\nusername:{username}")
full_name = f"{user_info['first']} {user_info['last']}"
location = user_info['location']

print(f"\tFull name: {full_name.title()}")
print(f"\tLocation: {location.title()}")

第六章 用户输入和while循环

6.1 input()函数的工作原理

1
2
message = input("Tell me something ,and I will repeat it back to you :")
print(message)
  1. 编写清晰的提示
1
2
name = input("Please enter your name:")
print(f"\nHello,{name}!")

运算符+=在赋给变量时在追加一个字符串

  1. 使用int()来获取数值输入

使用input()函数时,Python会将用户输入解读为字符串,可以使用int()将输入的字符串转换为数值

1
2
3
4
5
6
height = input("How tall are you,in inches?")
height = int (height)
if height >= 48:
print("\nYou're tall enough to ride!")
else:
print("\nYou'll be able to ride when you're a little older.")
  1. 求模运算符

求模运算符(%)可以将两个数相除并返回余数

判断是奇数还是偶数
1
2
3
4
5
6
7
number = input("Enter a number,and I'll tell you if it's even or odd:")
number = int(number)

if number % 2 == 0:
print(f"\nThe number {number} is even.")
else:
print(f"\nThe number {number} is odd.")

6.2 while循环简介

for循环用于针对集合中的每个元素执行一个代码块,而while循环则不断进行直到指定的条件不再满足为止。

  1. 使用while循环
1
2
3
4
current_number = 1
while current_number <= 5:
print(current_number)
current_number += 1
  1. 让用户选择何时退出
1
2
3
4
5
6
7
8
prompt = "\nTell me something,and I'll repeat it back to you:"
prompt += "\nEnter 'quit' to end the program."

message = ""
while message != 'quit':
message = input(prompt)
if message != 'quit':
print(message)
  1. 使用标志

标志变量通常被初始化为True,然后程序运行时,在条件为真时将其设置为False

1
2
3
4
5
6
7
8
9
10
prompt = "\nTell me something,and I'll repeat it back to you:"
prompt += "\nEnter 'quit' to end the program."
active = True

while active:
message = input(prompt)
if message == 'quit':
active = False
else:
print(message)
  1. 使用break退出循环
1
2
3
4
5
6
7
8
9
10
prompt = "\nTell enter the name of a city you have visited:"
prompt += "\n(Enter 'quit' when you are finished.)"

while True:
city = input(prompt)

if city == 'quit':
break
else:
print(f"I'd love to go to {city.title()}")

在所有的Python循环中都可以使用break语句。例如,可使用break语句来退出遍历列表或字典的for循环。

  1. 在循环中使用continue
1
2
3
4
5
6
7
current_number = 0
while current_number < 10:
current_number += 1
if current_number % 2 == 0:
continue
else:
print(current_number)
  1. 避免无限循环

结束无限循环,可在输出区域中单击鼠标,再按CTRL + C

6.3 使用while循环处理列表和字典

  1. 在列表之间移动元素
1
2
3
4
5
6
7
8
9
10
unconfirmed_users = ['alice', 'brian', 'candace']
confirmed_users = []

while unconfirmed_users:
current_user = unconfirmed_users.pop()
print(f"Verifying user: {current_user.title()}")
confirmed_users.append(current_user)
print("\nThe following users have benn confirmed:")
for confirmed_user in confirmed_users:
print(confirmed_user.title())
  1. 删除为特定值得所有列表元素
1
2
3
4
5
6
pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)
while 'cat' in pets:
pets.remove('cat')

print(pets)
  1. 使用用户输入填充字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
responses = {}
polling_active = True

while polling_active:
name = input("\nWhat is your name?")
response = input("Which mountain would you like to climb someday?")

responses[name] = response

repeat = input("Would you like to let another person respond?(yes/no)")
if repeat.lower() == 'no':
polling_active = False

print("\n--- Poll Results ---")
for name,response in responses.items():
print(f"{name} would like to climb {response}")

第七章 函数

7.1 定义函数

1
2
3
4
def greet_user():
print("Hello!")

greet_user()
  1. 向函数传递信息
1
2
3
4
def greet_user(username):
print(f"Hello, {username.title()}!")

greet_user('jiaming')
  1. 实参和形参
    上述例子中uesrname为形参,jiaming为实参

7.2 传递实参

  1. 位置实参
1
2
3
4
5
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')
  1. 调用函数多次
  2. 位置实参的顺序很重要
  1. 关键字实参
    关键字实参不仅让你无需考虑函数调用中的实参顺序,而且清楚的指出了函数调用中的各个值得用途
1
2
3
4
5
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')

在使用关键字实参时,务必准确的指定函数定义中的形参名。

  1. 默认值

编写函数时,可以给每个形参指定默认值

1
2
3
4
5
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')

当使用默认值时,必须在形参列表中先列出没有默认值的形参,再列出所有默认值的形参。

  1. 等效的函数调用
1
2
3
4
5
6
7
8
9
def describe_pet(pet_name, animal_type='dog'):
# 一条名为Willie的小狗
describe_pet('willie')
describe_pet(pet_name='willie')

# 一只名为Harry的仓鼠
describe_pet('harry', 'hamster')
describe_pet(animal_type='hamster', pet_name='harry')
describe_pet(pet_name='harry', animal_type='hamster')
  1. 避免实参错误
    确保函数调用和函数定义匹配

7.3 返回值

函数返回的值称为返回值

  1. 返回简单的值
1
2
3
4
5
6
def get_formatted_name(first_name, last_name):
full_name = f"{first_name} {last_name}"
return full_name.title()

musician = get_formatted_name('jimi', 'hendrix')
print(musician)
  1. 让实参变成可选的
1
2
3
4
5
6
7
8
9
10
11
12
13
def get_formatted_name(first_name, last_name, middle_name=''):
if middle_name:
full_name = f"{first_name} {middel_name} {last_name}"
else:
full_name = f"{first_name} {last_name}"

return full_name.title()


musician = get_formatted_name('jimi', 'hendrix')
print(musician)
misician = get_formatted_name('john', 'hooker', 'lee')
print(misician)
  1. 返回字典
1
2
3
4
5
6
def build_person(first_name, last_name):
person = {'first': first_name,'last': last_name}
return person

musician = build_person('jimi', 'hendrix')
print(musician)
1
2
3
4
5
6
7
8
def build_person(first_name, last_name, age=None):
person = {'first': first_name,'last': last_name}
if age:
person['age'] = age
return person

musician = build_person('jimi', 'hendrix',age=27)
print(musician)
  1. 结合使用函数和while循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def get_formatted_name(first_name, last_name):
full_name = f"{first_name} {last_name}"
return full_name.title()

while True:
print("\nPlease tell me your name:")
print("(Enter 'q' at any time to quit)")
f_name = input("First name: ")
if f_name=='q':
break
l_name = input("Last name: ")
if l_name=='q':
break

formatted_name = get_formatted_name(f_name, l_name)
print(f"\nHello,{formatted_name}")

7.4 传递列表

1
2
3
4
5
6
def greet_users(names):
for name in names:
msg = f"Hello, {name.title()}!"
print(msg)
usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)
  1. 在函数中修改列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 首先创建一个列表,其中包含一些要打印的设计
unprinted_designs = ['phone case', 'robot pendant', 'dodecahedrom']
completed_models = []

# 模拟打印每个设计,直到没有来打印的设计为止
# 打印每个设计后,都将其移到列表completed_models中
while unprinted_designs:
current_design = unprinted_designs.pop()
print(f"Printing model: {current_design}")
completed_models.append(current_design)

# 显示打印好的所有模型
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def print_models(unprinted_designs, completed_models):
while unprinted_designs:
current_design = unprinted_designs.pop()
print(f"Printing model: {current_design}")
completed_models.append(current_design)

def show_completed_models(completed_models):
print("\nThe following models have been printed:")
for completed_model in completed_models:
print(completed_model)

unprinted_designs = ['phone case', 'robot pendant', 'dodecahedrom']
completed_models = []

print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)
  1. 禁止函数修改列表

要将列表的副本传递给函数,可以这样做:

1
function_name(list_name[:])

切片表示法[:]创建列表的副本,在上述示例中,如果不想清空未打印的设计列表,可像下面这样调用print_models():

1
print_models(unprinted_designs[:], completed_models)

7.5 传递任意数量的实参

1
2
3
4
5
def make_pizza(*toppings):
print(toppings)

make_pizza('peperoni')
make_pizza('mushrooms', 'green pepepers', 'extra cheese')
1
2
3
4
5
6
7
def make_pizza(*toppings):
print("\nMaking a pizza with the following toppings:")
for topping in toppings:
print(f"- {topping}")

make_pizza('pepperoin')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

形参名中*toppings中的星号让python创建一个名为toppings的元组,该元组包含函数收到的所有值。

  1. 结合使用位置实参和任意数量的实参

如果要让函数接收不同类型的实参,必须在函数定义中将接受任意数量实参的形参放在最后。Python先匹配位置实参关键字实参,再将余下的实参都收集到最后一个形参中。

1
2
3
4
5
6
7
def make_pizza(size, *toppings):
print(f"\nMaking a {size}-inch pizza with the following toppings:")
for topping in toppings:
print(f"- {topping}")

make_pizza(16, 'pepperoni')
make_pizza(12,'mushrooms', 'green peppers', 'extra cheese')

会经常看到通用形参名*args,它也这样收集任意数量的位置实参。

  1. 使用任意数量的关键字实参
1
2
3
4
5
6
7
8
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的形参,它用于收集任意数量的关键字实参。

7.6 将函数存储在模块中

  1. 导入整个模块

要让函数是可导入的,得先创建模块。模块是扩展名.py文件,包含要导入程序的代码。

创建一个包含make_pizza()函数的模块
1
2
3
4
def make_pizza(size, *toppings):
print(f"\nMaking a {size}-inch pizza with the following topping:")
for topping in toppings:
print(f"- {topping}")
在同一目录下创建.py文件再导入刚刚创建的模块
1
2
3
import make_pizza

pizza.make_pizza(16,'pepperoni')

调用被导入模块中的函数,可指定被导入模块的名称函数名,并用句点隔开

导入整个模块,使用import module_name语句。

  1. 导入特定的函数

如果只想导入一个特定的函数,可使用from module_name import function_name语句。(用逗号分隔函数名)

1
2
3
from pizza import make_pizza

make_pizza(16,'pepperoni')

如果使用这种语法,在调用函数时则无需使用句点,由于在import语句中显示的导入了函数,因此在调用时无需指定其名称即可

  1. 使用as给函数指定别名

如果不想使用函数原本的名称,或名称可能与变量名冲突,可使用as关键字给函数指定别名。

1
2
3
from pizza import make_pizza as mp

mp(16,'pepperoni')

使用as给函数指定别名,在调用函数时,必须使用别名。

  1. 使用as给模块指定别名

如果不想使用模块原本的名称,或名称可能与变量名冲突,可使用as关键字给模块指定别名。

1
2
3
import pizza as p

p.make_pizza(16,'pepperoni')
  1. 导入模块中的所有函数

如果想要导入模块中的所有函数,可使用*通配符。

1
2
3
from pizza import *

make_pizza(16,'pepperoni')

第八章 类

8.1 创建和使用类

  1. 创建Dog类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Dog:
# 一次模拟小狗的简单尝试
def __init__(self,name,age):
# 初始化属性name和age
self.name = name
self.age = age

def sit(self):
# 模拟小狗收到命令时坐下
print(f"{self.name} is now siting.")

def roll_over(self):
# 模拟小狗收到命令时打滚
print(f"{self.name} rolled over!")

  1. 类定义由类名和一对圆括号组成。类名的命名规则与变量名相同,但首字母大写
  2. 类定义内部是一系列类方法,它们与普通函数类似,但要使用self参数。
  3. 类方法的第一个参数必须是self,表示实例本身。

_init_()是一种特殊方法,每当你根据Dog类创建新实例时,Python都会自动运行它。

  1. 根据类创建实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Dog:
# 一次模拟小狗的简单尝试
def __init__(self,name,age):
# 初始化属性name和age
self.name = name
self.age = age

def sit(self):
# 模拟小狗收到命令时坐下
print(f"{self.name} is now siting.")

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.")
  1. 访问属性
1
类名.属性名
  1. 调用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Dog:
# 一次模拟小狗的简单尝试
def __init__(self,name,age):
# 初始化属性name和age
self.name = name
self.age = age

def sit(self):
# 模拟小狗收到命令时坐下
print(f"{self.name} is now siting.")

def roll_over(self):
# 模拟小狗收到命令时打滚
print(f"{self.name} rolled over!")

my_dog = Dog('willie',6)
my_dog.sit()
my_dog.roll_over()
  1. 创建多个实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Dog:
# 一次模拟小狗的简单尝试
def __init__(self,name,age):
# 初始化属性name和age
self.name = name
self.age = age

def sit(self):
# 模拟小狗收到命令时坐下
print(f"{self.name} is now siting.")

def roll_over(self):
# 模拟小狗收到命令时打滚
print(f"{self.name} rolled over!")

my_dog = Dog('willie',6)
your_dog = Dog('Lucy',3)
print(f"My dog's name is {my_dog.name}")
print(f"My dog is {my_dog.age} years old.")
my_dog.sit()
my_dog.roll_over()
print(f"My dog's name is {your_dog.name}")
print(f"My dog is {your_dog.age} years old.")
your_dog.sit()

8.2 使用类和实例

  1. Car类
1
2
3
4
5
6
7
8
9
10
11
12
13
class Car:
# 一次模拟汽车的简单尝试
def __init__(self,make,model,year):
self.make = make
self.model = model
self.year = year

def get_descriptive_name(self):
long_name = f"{self.year} {self.make} {self.model}"
return long_name.title()

my_new_car = Car('audi','a4','2024')
print(my_new_car.get_descriptive_name())
  1. 给属性指定默认值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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.")

my_new_car = Car('audi','a4','2024')
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()
  1. 修改属性的值
  1. 直接修改属性的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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.")

my_new_car = Car('audi','a4','2024')
print(my_new_car.get_descriptive_name())

my_new_car.odometer_reading = 23
my_new_car.read_odometer()
  1. 添加方法修改属性的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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,nileage):
self.odometer_reading = nileage

my_new_car = Car('audi','a4','2024')
print(my_new_car.get_descriptive_name())

my_new_car.update_odometer(23)
my_new_car.read_odometer()
1
2
3
4
5
6
--snip
def update_odometer(self,nileage):
if nileage >= odometer:
self.odometer_reading = nileage
else:
print("You can't roll back an odometer!")
  1. 通过方法让属性的值递增
1
2
3
4
5
6
7
8
9
10
11
12
13
class Car:
--snip
def update_odometer(self,nileage):
--snip

def increment_odometer(self,miles):
self.odometer_reading += miles

my_new_car = Car('subaru','outback','2019')
print(my_new_car.get_descriptive_name())

my_new_car.increment_odometer(300)
my_new_car.read_odometer()

8.3 继承

  1. 子类的__init__()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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,nileage):
self.odometer_reading = nileage

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())
  1. 在定义子类时,必须在括号内指定父类的名称
  2. super()是一个特殊的函数,能够调用父类的方法,实例中的super().__init__()方法,让ElectricCar类包含这个方法定义的所有属性
  1. 给子类定义属性和方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
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,nileage):
self.odometer_reading = nileage

def increment_odometer(self,miles):
self.odometer_reading += miles

class ElectricCar(Car):
# 电动汽车的独特之处
def __init__(self,make,model,year):
# 初始化父类的属性
super().__init__(make,model,year)
self.battery_size = 40

def describe_battery(self):
print(f"This car has a {self.battery_size}-kWh battery.")

my_leaf = ElectricCar('nissan','leaf','2024')
print(my_leaf.get_descriptive_name())
my_leaf.describe_battery()
  1. 重写父类中的方法
假设Car类有一个名为fill_gas_tank()的方法,它对电动汽车来说毫无意义,因此你可能想重写他
1
2
3
4
class ElectricCar(Car):
--snip
def fill_gas_tank(self):
print("This car doesn't need a gas tank!")
  1. 将实例用作属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Car:
--snip

class Battery:
def __init__(self,battery_size=40):
self.battery_size = battery_size

def discribe_battery(self):
print(f"This car has a {self.battery_size}-kWh battery.")


class ElectricCar(Car):
# 电动汽车的独特之处
def __init__(self,make,model,year):
# 初始化父类的属性
super().__init__(make,model,year)
self.battery = Battery()


my_leaf = ElectricCar('nissan','leaf','2024')
print(my_leaf.get_descriptive_name())
my_leaf.battery.discribe_battery()

将实例赋给属性后,再调用其中的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Car:
--snip

class Battery:
--snip
def get_range(self):
if self.battery_size == 40:
range = 150
elif self.battery_size == 65:
range = 225

print(f"This car can go about {range} miles on a full charge")


class ElectricCar(Car):
# 电动汽车的独特之处
def __init__(self,make,model,year):
# 初始化父类的属性
super().__init__(make,model,year)
self.battery = Battery()


my_leaf = ElectricCar('nissan','leaf','2024')
print(my_leaf.get_descriptive_name())
my_leaf.battery.discribe_battery()
my_leaf.battery.get_range()

8.4 导入类

  1. 导入单个类

类似导入模块

1
from module_name import 类名
  1. 在一个模块中存储多个类
1
from module_name import 类名
  1. 从一个模块中导入多个类
1
from module_name import 类名,类名···
  1. 导入整个模块
1
import module_name

使用module_name.类名访问需要的类

  1. 导入模块中的所有类
1
from module_name import *

不推荐使用这种方法,不清楚使用了模块中的哪些类

  1. 在一个模块中导入另一个模块
1
from module_name import 类名
  1. 使用别名
1
from module_name import 类名 as 别名
1
import module_name as 别名

8.5 Python标准库

Python标准库是一组模块,在安装Python时已经包含在内

第九章 文件和异常

9.1 读取文件

  1. 读取文件的全部内容
1
2
3
4
from pathlib import Path
path = Path('test.txt')
contenes = path.read_text()
print(contenes)

使用Path类读取文件

  1. 相对文件路径和绝对文件路径
1
path = Path("text_files/filename.txt")
1
path = Path("C:/Users/Administrator/Desktop/text_files/filename.txt")
  1. 相对文件路径:相对于当前运行程序的所在目录的指定位置
  1. 绝对文件路径:以系统的根文件夹为起点

在显示文件路径时,Windows系统使用反斜杠(\)而不是斜杠(/),但是你在代码中应该始终使用斜杠

  1. 访问文件中的各行
1
2
3
4
5
6
7
from pathlib import Path
path = Path('test.txt')
contenes = path.read_text()

lines = contenes.splitlines()
for line in lines:
print(line)
  1. 使用文件的内容
1
2
3
4
5
6
7
8
9
10
11
from pathlib import Path
path = Path('test.txt')
contenes = path.read_text()

lines = contenes.splitlines()
pi_string = ''
for line in lines:
pi_string += line.lstrip()

print(pi_string)
print(len(pi_string))
  1. 使用lstrip()方法去除每一行开头的空格
  2. 在读取文本文件时,Python将其中的所有文本都解释为字符串。如果读取的是数,并且要将其作为数值使用,就必须使用int()函数将其转换为整数,或者使用float()函数将其转化为浮点数
  1. 包含100万位的大型文件
1
2
3
4
5
6
7
8
9
10
11
from pathlib import Path
path = Path('test.txt')
contenes = path.read_text()

lines = contenes.splitlines()
pi_string = ''
for line in lines:
pi_string += line.lstrip()

print(f"{pi_string[:52]}...")
print(len(pi_string))

在处理的数据量方面,Python没有任何限制。只要系统的内存足够大,你想处理多少数据就可以处理多少数据

  1. 圆周率值中包含你的生日吗
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pathlib import Path
path = Path('test.txt')
contenes = path.read_text()

lines = contenes.splitlines()
pi_string = ''
for line in lines:
pi_string += line.lstrip()

birthday = input("Enter your birthday, in the form mmddyy:")
if birthday in pi_string:
print("包含")
else:
print("不包含")

9.2 写入文件

  1. 写入一行
1
2
3
4
from pathlib import Path

path = Path('test.txt')
path.write_text('Hello, world!')
  1. Python只能将字符串写入文本文件,如果要将数值数据存储在文本文件中,必须先使用函数str()将其转化为字符串格式
  2. 如果path变量对应的路径指向的文件不存在,就创建它
  1. 写入多行
1
2
3
4
5
6
7
8
from pathlib import Path

contents = "I love programming.\n"
contents += "I love creating new games.\n"
contents += "I love learning new things.\n"

path = Path('test.txt')
path.write_text(contents)

如果指定的文件已存在,write_text()将删除其内容,并将指定的内容写入其中

9.3 异常

  1. 处理ZeroDivisionError异常
1
print(5/0)

运行程序时,Python将引发ZeroDivisionError异常,并显示一条错误消息,将停止运行程序

  1. 使用try-except代码块
1
2
3
4
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")

使用try-except代码块,可以捕获异常并处理它。如果程序没有引发任何异常,那么except代码块将不会被执行

  1. 使用异常避免崩溃
1
2
3
4
5
6
7
8
9
10
11
12
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:")
if second_number =='q':
break
answer = int(first_number) / int(second_number)
print(answer)

如果用户输入的不是数字,那么程序将引发ValueError异常,并停止运行程序

  1. else代码块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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:")
if second_number =='q':
break
try:
answer = int(first_number) / int(second_number)
except ZeroDivisionError:
print("You can't divide by zero!")
else:
print(answer)

如果程序没有引发任何异常,那么else代码块将被执行

  1. 处理FileNotFoundError异常
1
2
3
4
5
# 不存在test.txt文件
from pathlib import Path

path = Path('test.txt')
contents = path.read_text(encoding='utf-8')
1
2
3
4
5
6
7
8
# 不存在test.txt文件
from pathlib import Path

path = Path('test.txt')
try:
contents = path.read_text(encoding='utf-8')
except FileNotFoundError:
print("Sorry, the file does not exist.")
  1. 分析文本
1
2
3
4
5
6
7
8
9
10
11
from pathlib import Path

path = Path('test.txt')
try:
contents = path.read_text(encoding='utf-8')
except FileNotFoundError:
print("Sorry, the file does not exist.")
else:
words = contents.split()
num_words = len(words)
print(f"The file {path} has about {num_words} words.")
  1. 使用多个文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pathlib import Path

def count_words(path):
try:
contents = path.read_text(encoding='utf-8')
except FileNotFoundError:
print(f"Sorry, the file {path} does not exist.")
else:
words = contents.split()
num_words = len(words)
print(f"The file {path} has about {num_words} words.")

filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
path = Path(filename)
count_words(path)

使用try-except代码块有两个重要优点,一是避免用户看到traceback,二是让程序可以继续分析能够找到的其他文件

  1. 静默失败
1
2
3
4
5
6
7
8
9
def count_words(path):
try:
contents = path.read_text(encoding='utf-8')
except FileNotFoundError:
pass
else:
words = contents.split()
num_words = len(words)
print(f"The file {path} has about {num_words} words.")

当发生错误时,既不会出现traceback,也没有任何输出

9.4 存储数据

  1. 使用json.dumps()和json.loads()
1
2
3
4
5
6
7
8
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.dumps()将列表转换为字符串,path.write_text()将字符串写入文件

1
2
3
4
5
6
7
8
from pathlib import Path
import json

path = Path('numbers.json')
contents = path.read_text()
numbers = json.loads(contents)

print(numbers)

path.read_text()读取文件内容,json.loads()将字符串转换为列表

  1. 保存和读取用户生成的数据
1
2
3
4
5
6
7
8
9
10
from pathlib import Path
import json

username = input("What is your name?")

path = Path('username.json')
contents = json.dumps(username)
path.write_text(contents)

print(f"We'll remember you when you come back,{username}!")
1
2
3
4
5
6
7
8
from pathlib import Path
import json

path = Path('username.json')
contents = path.read_text()
username = json.loads(contents)

print(f"Welcome back,{username}")
1
2
3
4
5
6
7
8
9
10
11
12
from pathlib import Path
import json

path = Path('username.json')
if path.exists():
contents = path.read_text()
username = json.loads(contents)
print(f"Welcome back,{username}")
else:
username = input("What is your name?")
path.write_text(json.dumps(username))
print(f"We'll remember you next time,{username}")
  1. 重构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pathlib import Path
import json

def greet_user():
path = Path('username.json')
if path.exists():
contents = path.read_text()
username = json.loads(contents)
print(f"Welcome back,{username}")
else:
username = input("What is your name?")
path.write_text(json.dumps(username))
print(f"We'll remember you next time,{username}")

greet_user()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pathlib import Path
import json

def get_stored_username(path):
if path.exists():
contents = path.read_text()
return json.loads(contents)
else:
return None

def greet_user():
path = Path('username.json')
username = get_stored_username(path)
if username:
print(f"Welcome back,{username}")
else:
username = input("What is your name?")
path.write_text(json.dumps(username))
print(f"We'll remember you next time,{username}")

greet_user()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from pathlib import Path
import json

def get_stored_username(path):
if path.exists():
contents = path.read_text()
return json.loads(contents)
else:
return None

def get_new_username(path):
username = input("What is your name?")
path.write_text(json.dumps(username))
return username

def greet_user():
path = Path('username.json')
username = get_stored_username(path)
if username:
print(f"Welcome back,{username}")
else:
username = get_new_username(path)
print(f"We'll remember you next time,{username}")

greet_user()

第十章 测试代码

10.1 使用pip安装pytest

  1. 更新pip
1
python -m pip install --upgrade pip
1
python -m pip install --upgrade <package>
  1. 安装pytest
1
python -m pip install --user pytest
1
python -m pip install --user <package>

10.2 测试函数

测试函数中验证代码格式assert 变量名 == 指定的值

10.3 测试类

  1. 各种断言

| 断言 | 用途 |
| -------- | -------- | ----|
| assert a == b | 断言两个值相等 |
| assert a != b | 断言两个值不等 |
| assert a | 断言a的布尔值为True |
| assert assert not a | 断言a的布尔值为False |
| assert element in list | 断言元素在列表中 |
| assert element not in list | 断言元素不在列表中 |

这里列出的只是九牛一毛,测试能包含任意可用条件语句表示的断言