Python学习记录
第一章 变量和简单的数据类型
1.1 字符串
- 修改字符串的大小写
1
2
3变量名.title( ) # 首字母大写,其他为小写
变量名.lower( ) # 全部小写
变量名.upper() # 全大写 - 字符串的拼接
1
f"字符串 {变量名} {变量名}"
- 删除空白
1
2
3变量名.rstrip() # 删除右侧空白
变量名.lstrip() # 删除左侧空白
变量名.strip() # 删除两侧空白 - 删除前缀
1
变量名.removeprefix(前缀)
1.2 数
- 数中的下划线
1
universe_age=14_000_000 # 14000000
- 同时给多个变量赋值
1
a,b=10,20
第二章 列表简介
2.1 修改、添加和删除元素
- 修改
1
列表名[索引] = 元素
- 添加
1
2
3列表名.append(元素) # 添加到列表末尾
列表名.insert(索引,元素) # 在指定位置添加元素
列表名 += [元素1,元素2] # 添加多个元素 - 删除
1
2
3del 列表名[索引] # 删除指定位置元素
列表名.pop(索引) # 删除指定位置元素,并返回被删除的元素
列表名.remove(元素) # 删除第一个出现的指定元素
2.2 管理列表
- 使用sort()方法对列表进行永久排序
1
2列表名.sort( ) # 按字母顺序从小到大排序
列表名.sort(reverse=True) # 按字母顺序从大到小排序 - 使用sorted()函数对列表进行临时排序
1
sorted(列表名) # 按字母顺序从小到大排序
- 列表反转
1
列表名.reverse()
- 确定指定元素的个数、列表长度
1
2列表名.count(元素) # 返回指定元素的个数
len(列表名) # 返回列表长度
第三章 操作列表
3.1 遍历整个列表
- 遍历列表
1
2for 变量名 in 列表名:
print(变量名)
3.2创建数值列表
- 使用range( )函数
1
2
3# 创建1-5的列表
for value in range(1,5):
print(value) - 使用range()创建数值列表
1
2
3
4
5
6
7
8
9
10numbers = 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) - 对数值列表执行简单的统计计算
1
2digits = [1,2,3,4,5,6,7,8,9]
print(min(digits), max(digits), sum(digits)) - 列表推导式
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
2
3
4
5
6
7players = ['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 - 遍历切片
1
2
3
4players = ['charles','martina','michael','florence','eli']
print("Here are the first three aplayers on my team:")
for player in players[:3]:
print(player.title()) - 复制列表
复制列表时,只是创建了新列表的引用,而不是创建副本
1
2
3
4my_food = ['pizza','falafel', 'carrot coke']
friend_food = my_food[:]
print(my_food)
print(friend_food)
3.4元组
元组是不能修改元素的列表,但可以重新赋值
第四章 if语句
4.1 if语句
- 简单的if语句
1
2if 条件:
代码块 - if-else语句
1
2
3
4if 条件1:
代码块1
elif 条件2:
代码块2 - if-elif-else语句
1
2
3
4
5
6if 条件1:
代码块1
elif 条件2:
代码块2
else:
代码块3 - 使用多个elif代码块
1
2
3
4
5
6
7
8if 条件1:
代码块1
elif 条件2:
代码块2
elif 条件3:
代码块3
else:
代码块4
4.2 使用if语句处理列表
检查特殊元素
1
2
3
4
5
6
7
8request_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!")确定列表为空
1
2
3
4
5
6
7
8request_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
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
2
3
4alien_0 = {'color': 'green', 'points': 5}
print(alien_0['color']) # 访问字典中的值
print(alien_0['points'])
5.2 使用字典
字典
是一系列键值对,每个键都与一个值关联,可以使用键来访问与之关联的值。
与键相关联的值的类型可以是数字、字符串、列表乃至字典。
- 访问字典中的值
[]
中放置的是键,而不是索引。1
2
3
4alien_0 = {'color': 'green', 'points': 5}
new_points = alien_0['points']
print(f"You just earned {new_points} points!") - 添加键值对
1
2
3
4
5
6alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0) - 从创建一个空字典开始
1
2
3
4alien_0 = {}
alien_0['color'] = 'green'
alien_0['points'] = 5
print(alien_0) - 修改字典中的值
1
2
3
4
5alien_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
语句可以删除字典中的键值对,也可以使用pop()
方法删除键值对1
2
3
4
5alien_0 = {'color':'green','points':5}
print(alien_0)
del alien_0['points']
print(alien_0) - 由类似的对象组成字典
1
2
3
4
5
6
7
8favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'rust',
'phil': 'python',
}
languages = favorite_languages['sarah'].title()
print(f"Sarah's favorite language is {languages}") - 使用get()来访问值
get()
方法返回与键相关联的值,如果字典中没有指定的键,则返回None
或指定值。1
2
3alien_0 = {'color': 'green', 'speed': 'slow'}
point_value = alien_0.get('points', 'No point value assigned.')
print(point_value)
5.3 遍历字典
- 遍历所有的键值对
items()
方法返回一个包含字典中所有键值对的列表,每个键值对用两个元素表示。1
2
3
4
5
6
7
8user_0 = {
'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
for key,value in user_0.items():
print(f"\nKey: {key}")
print(f"Value: {value}") - 遍历字典所有的键
keys()
方法返回一个包含字典中所有键的列表。1
2
3
4
5
6
7
8favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
for name in favorite_languages.keys():
print(name.title()) - 按特定的顺序遍历字典中的所有键
使用sorted()函数来获得按特定顺序排列的键列表的副本
1
2
3
4
5
6
7
8
9favorite_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.") - 遍历字典中的所有值
values()
方法返回一个包含字典中所有值的列表。1
2
3
4
5
6
7
8
9
10favorite_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
10favorite_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
2languages = {'python', 'rust', 'python', 'c'}
print(languages)集合和字典很容易混淆,因为它们都是一对花括号定义的。当花括号没有键值对时,定义的很可能是集合。不同于列表和字典,集合不会以特定的顺序存储元素。
5.4 嵌套
字典列表
1
2
3
4
5
6
7alien_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
9aliens = []
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
18aliens = []
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
2
3
4
5
6
7
8
9pizza = {
'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
16favorite_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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20users = {
'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 | message = input("Tell me something ,and I will repeat it back to you :") |
- 编写清晰的提示
1
2name = input("Please enter your name:")
print(f"\nHello,{name}!")运算符
+=
在赋给变量时在追加一个字符串 - 使用int()来获取数值输入
使用input()函数时,Python会将用户输入解读为字符串,可以使用
int()
将输入的字符串转换为数值1
2
3
4
5
6height = 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
2
3
4
5
6
7number = 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循环
则不断进行直到指定的条件不再满足为止。
- 使用while循环
1
2
3
4current_number = 1
while current_number <= 5:
print(current_number)
current_number += 1 - 让用户选择何时退出
1
2
3
4
5
6
7
8prompt = "\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) - 使用标志
标志变量通常被初始化为
True
,然后程序运行时,在条件为真时将其设置为False
1
2
3
4
5
6
7
8
9
10prompt = "\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) - 使用
break
退出循环1
2
3
4
5
6
7
8
9
10prompt = "\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循环。 - 在循环中使用continue
1
2
3
4
5
6
7current_number = 0
while current_number < 10:
current_number += 1
if current_number % 2 == 0:
continue
else:
print(current_number) - 避免无限循环
结束无限循环,可在输出区域中单击鼠标,再按CTRL + C
6.3 使用while循环处理列表和字典
- 在列表之间移动元素
1
2
3
4
5
6
7
8
9
10unconfirmed_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
2
3
4
5
6pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)
while 'cat' in pets:
pets.remove('cat')
print(pets) - 使用用户输入填充字典
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16responses = {}
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 | def greet_user(): |
- 向函数传递信息
1
2
3
4def greet_user(username):
print(f"Hello, {username.title()}!")
greet_user('jiaming') - 实参和形参
上述例子中uesrname
为形参,jiaming
为实参
7.2 传递实参
位置实参
1
2
3
4
5def 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
3
4
5def 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
2
3
4
5def 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
2
3
4
5
6
7
8
9def 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')- 避免实参错误
确保函数调用和函数定义匹配
7.3 返回值
函数返回的值称为返回值
- 返回简单的值
1
2
3
4
5
6def 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
2
3
4
5
6
7
8
9
10
11
12
13def 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
2
3
4
5
6def 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
8def 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)结合使用函数和while循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16def 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 | def greet_users(names): |
- 在函数中修改列表
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
16def 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
function_name(list_name[:])
切片表示法
[:]
创建列表的副本,在上述示例中,如果不想清空未打印的设计列表,可像下面这样调用print_models():1
print_models(unprinted_designs[:], completed_models)
7.5 传递任意数量的实参
1 | def make_pizza(*toppings): |
1 | def make_pizza(*toppings): |
形参名中*toppings
中的星号让python创建一个名为toppings的元组,该元组包含函数收到的所有值。
- 结合使用位置实参和任意数量的实参
如果要让函数接收不同类型的实参,必须在函数定义中将接受任意数量实参的形参放在最后。Python先匹配
位置实参
和关键字实参
,再将余下的实参都收集到最后一个形参中。1
2
3
4
5
6
7def 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
2
3
4
5
6
7
8def 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 将函数存储在模块中
- 导入整个模块创建一个包含make_pizza()函数的模块
要让函数是可导入的,得先创建模块。
模块
是扩展名.py
文件,包含要导入程序的代码。在同一目录下创建.py文件再导入刚刚创建的模块1
2
3
4def make_pizza(size, *toppings):
print(f"\nMaking a {size}-inch pizza with the following topping:")
for topping in toppings:
print(f"- {topping}")1
2
3import make_pizza
pizza.make_pizza(16,'pepperoni')调用被导入模块中的函数,可指定被导入模块的
名称
和函数名
,并用句点隔开导入整个模块,使用
import module_name
语句。 - 导入特定的函数
如果只想导入一个特定的函数,可使用
from module_name import function_name
语句。(用逗号分隔函数名)1
2
3from pizza import make_pizza
make_pizza(16,'pepperoni')如果使用这种语法,在调用函数时则无需使用句点,由于在
import
语句中显示的导入了函数,因此在调用时无需指定其名称即可 - 使用as给函数指定别名
如果不想使用函数原本的名称,或名称可能与变量名冲突,可使用
as
关键字给函数指定别名。1
2
3from pizza import make_pizza as mp
mp(16,'pepperoni')使用as给函数指定别名,在调用函数时,必须使用别名。
- 使用as给模块指定别名
如果不想使用模块原本的名称,或名称可能与变量名冲突,可使用
as
关键字给模块指定别名。1
2
3import pizza as p
p.make_pizza(16,'pepperoni') - 导入模块中的所有函数
如果想要导入模块中的所有函数,可使用
*
通配符。1
2
3from pizza import *
make_pizza(16,'pepperoni')
第八章 类
8.1 创建和使用类
创建Dog类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class 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!")- 类定义由类名和一对圆括号组成。类名的命名规则与变量名相同,但
首字母大写
。 - 类定义内部是一系列类方法,它们与普通函数类似,但要使用
self
参数。 - 类方法的第一个参数必须是
self
,表示实例本身。
_init_()
是一种特殊方法,每当你根据Dog类创建新实例时,Python都会自动运行它。- 类定义由类名和一对圆括号组成。类名的命名规则与变量名相同,但
根据类创建实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24class 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 使用类和实例
- Car类
1
2
3
4
5
6
7
8
9
10
11
12
13class 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class 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
2
3
4
5
6
7
8
9
10
11
12
13class 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 继承
- 子类的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
28class 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())- 在定义子类时,必须在括号内指定父类的名称
super()
是一个特殊的函数,能够调用父类的方法,实例中的super().__init__()
方法,让ElectricCar类包含这个方法定义的所有属性
- 给子类定义属性和方法
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
33class 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() - 重写父类中的方法假设Car类有一个名为fill_gas_tank()的方法,它对电动汽车来说毫无意义,因此你可能想重写他
1
2
3
4class ElectricCar(Car):
--snip
def fill_gas_tank(self):
print("This car doesn't need a gas tank!") - 将实例用作属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22class 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
26class 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
from module_name import 类名
- 在一个模块中存储多个类
1
from module_name import 类名
- 从一个模块中导入多个类
1
from module_name import 类名,类名···
- 导入整个模块
1
import module_name
使用
module_name.类名
访问需要的类 - 导入模块中的所有类
1
from module_name import *
不推荐使用这种方法,不清楚使用了模块中的哪些类
- 在一个模块中导入另一个模块
1
from module_name import 类名
- 使用别名
1
from module_name import 类名 as 别名
1
import module_name as 别名
8.5 Python标准库
Python标准库
是一组模块,在安装Python时已经包含在内
第九章 文件和异常
9.1 读取文件
- 读取文件的全部内容
1
2
3
4from pathlib import Path
path = Path('test.txt')
contenes = path.read_text()
print(contenes)使用
Path
类读取文件 相对文件路径和绝对文件路径
1
path = Path("text_files/filename.txt")
1
path = Path("C:/Users/Administrator/Desktop/text_files/filename.txt")
相对文件路径
:相对于当前运行程序的所在目录的指定位置绝对文件路径
:以系统的根文件夹为起点在显示文件路径时,Windows系统使用反斜杠
(\)
而不是斜杠(/)
,但是你在代码中应该始终使用斜杠
访问文件中的各行
1
2
3
4
5
6
7from pathlib import Path
path = Path('test.txt')
contenes = path.read_text()
lines = contenes.splitlines()
for line in lines:
print(line)使用文件的内容
1
2
3
4
5
6
7
8
9
10
11from 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))- 使用
lstrip()
方法去除每一行开头的空格 - 在读取文本文件时,Python将其中的所有文本都解释为字符串。如果读取的是数,并且要将其作为数值使用,就必须使用
int()
函数将其转换为整数,或者使用float()
函数将其转化为浮点数
- 使用
包含100万位的大型文件
1
2
3
4
5
6
7
8
9
10
11from 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
2
3
4
5
6
7
8
9
10
11
12
13
14from 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
2
3
4from pathlib import Path
path = Path('test.txt')
path.write_text('Hello, world!')Python
只能将字符串写入文本文件,如果要将数值数据存储在文本文件中,必须先使用函数str()
将其转化为字符串格式- 如果
path
变量对应的路径指向的文件不存在,就创建它
- 写入多行
1
2
3
4
5
6
7
8from 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 异常
- 处理ZeroDivisionError异常
1
print(5/0)
运行程序时,Python将引发
ZeroDivisionError
异常,并显示一条错误消息,将停止运行程序 - 使用try-except代码块
1
2
3
4try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")使用
try-except
代码块,可以捕获异常并处理它。如果程序没有引发任何异常,那么except
代码块将不会被执行 - 使用异常避免崩溃
1
2
3
4
5
6
7
8
9
10
11
12print("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
异常,并停止运行程序 - else代码块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16print("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
代码块将被执行 - 处理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
2
3
4
5
6
7
8
9
10
11from 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16from 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
2
3
4
5
6
7
8
9def 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 存储数据
- 使用json.dumps()和json.loads()
1
2
3
4
5
6
7
8from 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
8from 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
2
3
4
5
6
7
8
9
10from 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
8from 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
12from 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15from 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
21from 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
25from 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
- 更新pip
1
python -m pip install --upgrade pip
1
python -m pip install --upgrade <package>
- 安装pytest
1
python -m pip install --user pytest
1
python -m pip install --user <package>
10.2 测试函数
测试函数中验证代码格式assert 变量名 == 指定的值
10.3 测试类
- 各种断言
断言 | 用途 |
---|---|
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 | 断言元素不在列表中 |
这里列出的只是九牛一毛,测试能包含任意可用条件语句表示的断言