本文旨在记录读书过程中感兴趣,用得上的部分,不会过于详尽。
源代码:
---------------------------------------------------------------------------------------------------------------------------------
作者建议:①第一部分在42小时内快速浏览一遍,不用理解,混个眼熟。
②第二部分跟着项目实践精读,对应查阅第一部分的基础知识点,针对性地自我答疑。
只记录第一部分的内容。
第一部分 基础知识(1~11章)
第一章 起步
1、Windows
检查你的系统是否安装了python:在cmd里面打出'python'
关闭终端会话:按Ctrl+Z,再按回车,或执行命令exit()
2、Linux
用Ctrl+Alt+T 打开终端,打出'python3'
关闭终端:Ctrl+D 或exit()
将windows中每个命令python都替换为python3
3、 编写第一个程序
编写第一个程序前,在系统中创建一个名为python_work的文件夹,用于存储项目。
文件名和文件夹名称最好使用小写字母,并使用下划线代替空格。
4、命令窗口
在命令窗口中 cd 切换目录
dir windows下显示当前目录中的所有文件
ls Linux和macOS下显示当前目录中的所有文件
5、在终端运行python程序
windows:先cd到该目录下,再dir确定这个文集夹中包含X.py文件 ,直接python X.py运行。
linux:先cd到该目录下,再ls确定这个文集夹中包含X.py文件 ,直接python X.py运行。
第二章 变量和简单数据类型
1、运行hello_world.py 时发生的情况
print('Hello python word!')
运行hello_world.py 时,.py可以指出这是一个python程序,因此编辑器将使用python解释器来运行它。
注意使用的不是printf
2、变量
message ='Hello Python world!'
print(message)
输出:
Hello Python world!
其中message为变量,python始终记录变量的最新值。
有关变量的规则:
①变量名只能包含字母、数字和下划线(不能用数字打头)
②变量名中不能含有空格,但能使用下划线来分隔其中的单词
③不要将python关键字和函数名用作变量名
④变量名应既简短又具有描述性
⑤慎用小写字母l和大写字母O,容易将其与1和0弄混
Track back:
指一条记录,在解释器中指出解释器尝试运行代码时,在哪陷入困境。
Trackback(most recent call last):
File 'hello_world.py',line2,in<module>
print(mesage)
NameError:name 'mesage' is not defined
其中 File 'hello_world.py',line2,in<module>列出第二行有错误,
print(mesage)为错误点
NameError:name 'mesage' is not defined 为错误类型(此处为名称错误)
Name Error 一般有两种①变量赋值②输入变量名时拼写不正确
寻求帮助(Stack Overflow Redit):
你想做什么?------>应尽可能具体
你已尝试哪些方式?------>提供足够细节
结果如何?------>知道准确的错误消息很有用
3、字符串
一系列字符,在python中用括号括起来的都是字符串,可以是单引号或者双引号。
使用方法修改字符串的大小写
name = 'ada lovelace'
print(name.title())
输出
Ada Lovelace
方法title()为对数据的操作,把首字母大写,并把非首字母大写的改为小写。
方法是python对数据执行的操作。()内为额外信息。
相似的有 name.upper()都大写
name.lower()都小写 <-----可用于存储数据
在字符串中使用变量
f"{}"称为f字符串
first_name = "ada"
last_name = "lovelace"
full_name = f"{first_name}{last_name}"
print(full_name)
python通过把花括号内的变量替换为其值来设置字符串的格式。
使用指标符或换行符来添加空白
制表符指相当于tab,首行缩进\t,换行符为\n。
删除空白
使字符串末尾没有空白:rstrip()
last_name.rstrip()
last_name = last_name.rstrip()
剔除开头的空白lstrip(),同时剔除字符串两边的空白strip()
注意:单引号与撇号可能导致错误。请正确地使用单引号和双引号。
4、数
整数
可用+ - * / 表示加减乘除, **表示平方,用()修改运算次序。
浮点数
带小数点的数都可以称为浮点数。(小数点可出现在数的任意位置)
整数和浮点数
在其他任何运算中,如果一个操作数是整数,另一个操作数是浮点数,结果也总是浮点数。(结果包含的小数位数可能是不确定的。)
数中的下划线
书写很大的数的时候,可使用下划线将其中的数字分组,使其清晰易读。python不会打印其中的下划线。
universe_age = 14_000_000_000
print(universe_age)
输出14000000000
同时给多个变量赋值
x,y,z = 0 ,0 ,0
用逗号分开
常量
用全大写来表示某个变量为常量,其值始终不变。python没有内置的常量类型。
MAX_CONNECTIONS = 5000
5、注释
用#标识,让代码对你和其他人来说更容易理解。
第三章 列表简介
1、列表是什么?
列表是由一系列按特定顺序排列的元素组成。
python中,用[ ]表示列表,并用 , 分隔其中的元素。
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles)
输出:
['trek', 'cannondale', 'redline', 'specialized']
访问列表元素:
列表是有序的集合,可用元素位置(索引)告诉python。索引是从0开始。
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[0])
输出:
trek
如果:
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[0].title())
输出:
Trek
当索引指令为-1时,返回最后一个列表元素。同理-2为倒2,-3为倒3.
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[-1])
输出:
specialized
使用列表中的各个值:
message = f"My first bicucle was a {bicycals[0].title()}"
print(message)
输出:
My first bicycle was a Trek.
2、修改,添加和删除元素
修改元素
与访问很像,直接重新赋值覆盖。
motorcycles = ['honda', 'yamaha', 'suzuki']
motorcycles[0] = 'ducati'
print(motorcycles)
输出:
['ducati', 'yamaha', 'suzuki']
添加元素
①列表末尾添加元素 append()
motorcycles.append('ducati')
还可以创建空的列表,再用append()来添加元素
motorcycles = []
motorcycles.append('honda')
motorcycles.append('yamaha')
print(motorcycles)
输出:
['honda', 'yamaha']
②在列表中插入元素 insert()
motorcycles = ['honda','yamaha','suzuki']
motorcycles.insert(0,'ducati')
print(motorcycles)
输出:
['ducati','honda','yamaha','suzuki']
删除元素
①使用 del 语句,知道要删除元素的位置,删除后再无法访问
del motorcycle[0]
②使用 pop() 删除列表末尾的元素并可以接着使用它,相当于弹出栈顶元素。
poped_motorcycle = motorcycls.pop()
print(motorcycls)
print(poped_motorcycle)
# motorcycls.pop()是处理后的
# poped_motorcycle 被poped
输出:
['honda','yamaha']
suzuki
③使用pop(*)来删除任意位置的元素,在圆括号中指定要删除的元素索引,可以接着使用。
first_owned = motorcycles.pop(0)
④根据值删除元素remove() 得知道删除元素的值。也可以接着使用值。remove()只删除第一个指定的值,如果要删除的值可能在列表里出现多次,就需要使用循环来确保每个值都删除。
motorcycles.remove('ducati')
3、组织列表
修改是永久性的
使用方法sort()对列表永久排序
sort( ) 即按照字母顺序排序,也可以用于数组排序
cars = ['bmw', 'audi', 'toyota', 'subaru']
cars.sort()
print(cars)
输出:
['audi', 'bmw', 'subaru','toyota']
若要与字母方向相反,用sort(reverse = True)
cars.sort(reverse = True)
print(cars)
输出:
['toyota','subaru','bmw', 'audi']
使用函数sorted()对列表临时排序
sorted( )能按特定顺序显示列表元素,同时不影响原始排序。
print(sorted(cars))
print(cars)
输出:
['audi', 'bmw', 'subaru','toyota']
['bmw', 'audi', 'toyota', 'subaru']
与字母方向相反,用sorted(reverse = True)
倒着打印列表
用reverse( )
car.reverse()
确定列表的长度
用len( )
len(cars)
第四章 操作列表
1、便利整个列表
用for 循环
每一个缩进的代码行都是循环的一部分,避免缩进错误,不要漏了冒号:
magicians = ['a','b','c']
for magician in magicians :
print(magician)
输出:
a
b
c
其中magician为任意词。
2、创建数值列表
使用函数range()
for value in range(1,5):
print(value)
输出:
1
2
3
4
range()让python从指定一个值开始数,并在到达指定的第二个值时停止,故不包含5.
range(6)返回0~5共六个值。
使用rang()创建数字列表
使用 list( )
number = list(range(1,6))
print(number)
输出:
[1,2,3,4,5]
用range()时还可以指定步长
even_number = list(range(2,11,2)
print(number)
输出:
[2,4,6,8,10]
使用range()几乎可ui创建任何需要的数据集
squares = []
for value in range(1,11):
square = value**2
squares.sppend(square)
print(squares)
输出:
[1,4,9,16,25,49,64,81,100]
找出数字列表的最大值、最小值和总和
max(),min(),sum()
列表解析
squares = [value**2 for value in range(1,11)]
print(aquares)
square 是列表名,
value**2 是用于生成要存储到列表中的值,
for value in range(1,11) 是用于给表达式提供值
3、使用列表的一部分
切片
列表中的部分元素
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[0:3])
输出:
['charles', 'martina', 'michael']
切片与range()一样都是到第2个索引之前的元素后停止
如果没有指定第一个索引,python将自动从列表开头开始:
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[:4])
输出:
['charles', 'martina', 'michael', 'florence']
要让切片终止于列表末尾:
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[2:])
输出:
['michael', 'florence', 'eli']
最后三个还可以携程:
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[-3:])
输出:
['michael', 'florence', 'eli']
遍历切片
for循环中使用切片
for player in players[:3]:
print(player.title())
复制列表
[:]
print(players[:])
friend_foods = my_foods[:]
把my_foods的副本给friend_food
若为friend_foods = mu_foods则两个都指向my_foods这个列表
4、元组
python 将不能修改的值称为不可变的,而不可变的列表称为元组。
定义元组
()
dimensions = (200,50)
print(dimensions[0])
print(dimensions[1])
输出:
200
50
注意:元组是由','标识的,()只是让元组看起来更整洁。
如果定义只包含一个元素的元组,必须再这个元素后面加上’,‘
my_t = (3,)
便利元组中的所有值
用for循环:
dimensions = (200,50)
for dimension in dimensions:
print(dimentsion)
输出:
200
50
修改元组变量
元组的元素不能修改,但存储元组的变量可赋值
dimensions = (200,50)
print dimensions
输出:
200
50
dimensions = (400,100)
print dimensions
输出
400
100
第五章 if语句
1、示例
cars = ['audi', 'bmw', 'subaru', 'toyota']
for car in cars:
if car == 'bmw':
print(car.upper())
else:
print(car.title())
输出:
Audi
BMW
Subaru
Toyota
2、条件测试
== 检查是否相等,会区分大小写
!= 检查是否不相等
< 小于
<= 小于等于
> 大于
>= 大于等于
可用and/or 检查多个条件
在运算符的两边加一个空格,便于看代码
检查特定值是否包含在列表中
in 或 not in
available_toppings = ['mushrooms', 'olives', 'green peppers']
'mushrooms' in available_toppings
输出:
True
if user not on banned_users:
print(..)
3、if 语句
简单的if语句
if conditional_test:
do something
if-else语句
两种情况:
if age < 4:
print()
else :
print()
if-elif-else结构
超过两种情况
elif可以用多个elif,其中else可省略
if age < 4:
print()
elif age < 18:
print()
else :
print()
使用if 语句处理列表
在运行for循环前确定列表是否为空很重要
if requesteds:
for ...
requested_toppings = ['mushrooms', 'french fries', 'extra cheese']
for requested_topping in requested_toppings:
if requested_topping = 'mushrooms':
print("Adding " + requested_topping + ".")
else:
print("Sorry, we don't have " + requested_topping + ".")
print("\nFinished making your pizza!")
Adding mushrooms.
Sorry, we don't have french fries.
Adding extra cheese.
Finished making your pizza!
第六章 字典
1、一个简单的字典
alien_0 = {'color': 'green', 'points': 5}
print(alien_0['color'])
print(alien_0['points'])
输出:
green
5
字典aline_0存储了颜色和分数
2、使用字典
{}
里面放一系列键值对,中间用','分隔,键值对是两个相关联的值。
访问字典中的值
要获取与键值相关联的值,可依次指定字典名和放在[ ]内的键。
alien_0 = {'color': 'green'}
print(alien_0['color'])
输出:
green
添加键值对
可依次指定字典名,用[ ]括起键和相关联的值。
alien_0['x'] = 0
alien_0['y'] = 25
print(alien_0)
{'color': 'green', 'points': 5,'y':25,'x':0}
修改字典中的值
指定字典名,用[ ]阔起键,以及与该键相关联的新值。
alien_0['colcr'] = 'yellow'
删除键值对
del 永远消失
del alien_0['color']
由类似对象组成的字典
用多行来定义字典,在输入{}之后用回车,并在下一行缩进四个空格,并在每一个键值对后面加逗号。
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
用get()来访问值
指定键值可能不存在的情况
A = alien_0.get('points','Nopoint value')
print(point_value)
书上说如果没有points则会返回Nopoint value,若有points,则返回points,但我的代码运行不是这样
调用get()时,若没有指定第二个参数且指定键不存在
python将返回None
3、遍历字典
遍历所有键值对
用for循环 items()
user_0 = {'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
for key, value in user_0.items():
print(f"\nKey: {key}")
print(f"Value: {value}")
输出:
Key: username
Value: efermi
Key: first
Value: enrico
Key: last
Value: fermi
items()返回一个键值对列表
把每一个键值对赋值给指定的变量
遍历字典中的所有键
不需要使用字典中的值时使用.keys()
for name in favorite_languages.keys():
print(name.titles())
遍历字典时,会默认遍历所有的键,即keys()返回一个列表,其中包含字典中的所有键。
按特定顺序遍历字典中的所有键
sorted()临时排序,不影响原始排序。
for name in sorted(favorite_languages.keys()):
print(name.titles())
遍历字典中的所有值
values()来返回一个值列表,不包含任何值
for language in favorite_languages.values():
print(language.titles())
这种做法提取字典中所有的值,而没有考虑是否重复。
若有重复项,
①可使用集合set(),通过对包含重复元素的列表调用set().
for language in set(favorite_languages.values()):
print(language.titles())
②可使用一对{}直接创建集合,并在其中用‘,’分隔元素。
集合不能包含重复的元素
languages = {'python','ruby','python','c'}
集合和字典很容易混淆,都由{}定义。当{}内没有键值对时,定义的很有可能时集合,不同于列表和字典,集合不会以特定的顺序存储元素。
4、嵌套
将一系列字典存储在列表中,或将列表作为值存储在字典中,此为嵌套。
字典列表
首先创建n个字典,然后将这些字典都存储到一个列表中。
先创建一个空列表,再用range()生成字典,将字典放进列表。
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]
在字典中存储列表
首先创建一个字典,每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。
pizza = {
'crust': 'thick',
'toppings': ['mushrooms', 'extra cheese'],
}
在字典中存储字典
users = {'aeinstein': {'first': 'albert',
'last': 'einstein',
'location': 'princeton'},
'mcurie': {'first': 'marie',
'last': 'curie',
'location': 'paris'},
}
第七章 用户输入和while循环
1、函数input()的工作原理
函数input()让程序暂停运行,等待用户输入一些文本。获取用户输入后,python将其赋给一个变量,以便使用。
prompt = "\nTell me something, and I will repeat it back to you:"
message = input(prompt)
print(message)
使用int()来获取数值的输入
函数input()时,python将用户输入解读为字符串。
函数int()时,让python输入视为数值。
height = input("How tall are you, in inches? ")
height = int(height)
if height >= 36:
print("\nYou're tall enough to ride!")
else:
print("\nYou'll be able to ride when you're a little older.")
求模运算符
% 将两个数相除并返回余数
4%3
6%3
输出
1
0
2、while 循环简介
while循环不断运行,直到指定的条件不满足为止。
使用while循环
current_number = 1
while current_number <= 5:
print(current_number)
current_number += 1
输出:
1
2
3
4
5
让用户选择如何退出
定义了一个退出值,只要用户输入的不是这个值,程序就将接着运行。
prompt = "\nPlease tell me a city you have visited:"
prompt += "\n(Enter 'quit' when you are finished.) "
message = ' '
while message != 'quit':
message = input(prompt)
print(message)
以上不足之处是quit也被打印出来了,可改为:
prompt = "\nPlease tell me a city you have visited:"
prompt += "\n(Enter 'quit' when you are finished.) "
message = ' '
while message != 'quit':
message = input(prompt)
if message != 'quit':
print(message)
使用标志
flag(标志)简化了while语句
prompt = "\nTell me something, and I will 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退出循环
立即退出while循环,不再运行循环内的余下代码。 退出所有循环。
while True:
city = input(prompt)
if city == 'quit':
break
else:
print()
在循环中使用continue
执行continue语句,让python忽略余下的代码,并返回循环的开头。退出本次循环,进入下一循环。
Ctrl +C 退出无限循环
3、使用while 循环处理列表和字典
不应在for循环中修改列表,否则将导致python难以跟踪其中的元素。
可以用while 循环。
在列表之间移动元素
unconfirmed_users = ['alice', 'brian', 'candace']
confirmed_users = []
# Verify each user, until there are no more unconfirmed users.
# Move each verified user into the list of confirmed users.
while unconfirmed_users:
current_user = unconfirmed_users.pop()
print("Verifying user: " + current_user.title())
confirmed_users.append(current_user)
# Display all confirmed users.
print("\nThe following users have been confirmed:")
for confirmed_user in confirmed_users:
print(confirmed_user.title())
输出:
Verifying user: Candace
Verifying user: Brian
Verifying user: Alice
The following users have been confirmed:
Candace
Brian
Alice
删除为特定值的所有列表元素
remove() 与while一起用
删除列表中所有为特定值的元素
pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)
while 'cat' in pets:
pets.remove('cat')
print(pets)
输出:
['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
['dog', 'dog', 'goldfish', 'rabbit']
使用用户输入来填充字典
responses = {}
# Set a flag to indicate that polling is active.
polling_active = True
while polling_active:
# Prompt for the person's name and response.
name = input("\nWhat is your name? ")
response = input("Which mountain would you like to climb someday? ")
# Store the response in the dictionary:
responses[name] = response
# Find out if anyone else is going to take the poll.
repeat = input("Would you like to let another person respond? (yes/ no) ")
if repeat == 'no':
polling_active = False
# Polling is complete. Show the results.
print("\n--- Poll Results ---")
for name, response in responses.items():
print(name + " would like to climb " + response + ".")
第八章 函数
1、定义函数
def函数定义
greet_user()为函数,调用它时只需要输入greet_user()即可。
def greet_user(username):
"""Display a simple greeting."""
print("Hello, " + username.title() + "!")
greet_user('jesse')
输出:
Hello, Jesse!
文档字符串(docstring),用三个引号括起来,描述了函数是做什么的。
向函数传递信息
在()中添加一个变量,可让函数接受你给该变量指定的值。
def greet_users(names):
"""Print a simple greeting to each user in the list."""
for name in names:
msg = "Hello, " + name.title() + "!"
print(msg)
usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)
输出
Hello, Hannah!
Hello, Ty!
Hello, Margot!
实参和形参
username 为形参 jesse 为实参
2、传递参数
即存在多个实参的情况
位置实参:实参的顺序与形参的顺序相同
关键字实参:每个实参都由变量名和值组成;还可使用列表和字典。
位置参数
顺序相同
def describe_pet(pet_name, animal_type='dog'):
"""Display information about a pet."""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('harry', 'hamster')
输出:
I have a hamster.
My hamster's name is Harry.
①多次调用函数
②位置参数的序列很重要
关键字实参
传递给函数名称值对,直接在实参中将名称和值关联起来。
def describe_pet(pet_name, animal_type='dog'):
"""Display information about a pet."""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
# A dog named Willie.
describe_pet(pet_name='harry', animal_type='hamster')
输出:
I have a hamster.
My hamster's name is Harry.
默认值
def describe_pet(pet_name, animal_type='dog'):
"""Display information about a pet."""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
# A dog named Willie.
describe_pet(pet_name = 'willie')
#或者 describe_pet('willie')
是指给形参默认值 animal_type='dog'
注意:必须先在形参列表中列出没有默认值的形参,再列出有默认值的实参。
让python依然能够正确地解读位置实参。
等效的函数调用
def describe_pet(pet_name, animal_type='dog'):
"""Display information about a pet."""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('willie')
describe_pet(pet_name='willie')
describe_pet('harry', 'hamster')
describe_pet(pet_name='harry', animal_type='hamster')
describe_pet(animal_type='hamster', pet_name='harry')
注意:任何情况下都必须给pet_name提供实参。
指定实参时可采用位置方式,也可采用关键字方式。
3、返回值
函数可以处理一些数据,并返回一个或一组值,称为返回值。
可以用return语句将值返回到调用函数的代码行。
返回简单值
return
def get_formatted_name(first_name, last_name):
full_name = first_name + ' ' + last_name
return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician)
输出
Jimi Hendrix
让参数变成可选的
将该可能有或可能无的形参的默认值设为空字符串,并将其转移到形参列表的末尾。
def get_formatted_name(first_name, last_name, middle_name=''):
"""Return a full name, neatly formatted."""
if middle_name:
full_name = first_name + ' ' + middle_name + ' ' + last_name
else:
full_name = first_name + ' ' + last_name
return full_name.title()
musician = get_formatted_name('jimi', 'hendrix')
print(musician)
musician = get_formatted_name('john', 'hooker', 'lee')
print(musician)
输出:
Jimi Hendrix
John Lee Hooker
返回字典
def build_person(first_name, last_name):
"""Return a dictionary of information about a person."""
person = {'first': first_name, 'last': last_name}
return person
musician = build_person('jimi', 'hendrix')
print(musician)
def build_person(first_name, last_name, age=None):
"""Return a dictionary of information about a person."""
person = {'first': first_name, 'last': last_name}
if age:
person['age'] = age
return person
musician = build_person('jimi', 'hendrix', age=27)
print(musician)
age是形参,None是特殊值,表示变量没有值,可视为占位,相当于False。如果函数调用中包含形参age的值,这个值将被存储到字典中。
4、传递列表
将包含名字的列表传递给一个名为greet_users()的函数。
def greet_users(names):
"""Print a simple greeting to each user in the list."""
for name in names:
msg = "Hello, " + name.title() + "!"
print(msg)
usernames = ['hannah', 'ty', 'margot']
greet_users(usernames)
输出:
Hello, Hannah!
Hello, Ty!
Hello, Margot!
禁止函数修改列表
可以将列表副本传递给函数
fuction_name(list_name[:])
5、传递任意数量的实参
预先不知道函数需要接受多少个实参,用* 创造这个形参
例如:*toppings,不管调用语句提供了多少实参都可以。
*让python创造一个名为toppings的空元组,并将所有值都封装到元组中。
def make_pizza( *toppings):
print( toppings)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
输出:
('pepperoni',)
('mushrooms', 'green peppers', 'extra cheese')
结合使用位置实参和任意数量实参
若要接受不同类型的实参,必须将接纳任意数量实参的形参放最后,python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
def make_pizza(size, *toppings):
"""Summarize the pizza we are about to make."""
print("\nMaking a " + str(size) +
"-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
输出:
Making a 16-inch pizza with the following toppings:
- pepperoni
Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese
使用任意数量的关键字实参
可将函数编写能接受任意数量的键值对
def build_profile(first, last, **user_info):
"""Build a dictionary containing everything we know about a user."""
profile = {}
profile['first_name'] = first
profile['last_name'] = last
for key, value in user_info.items():
profile[key] = value
return profile
user_profile = build_profile('albert', 'einstein',
location='princeton',
field='physics')
print(user_profile)
输出:
{'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}
**user_info:让python创建一个名为user_info的空字典。并将收到的所有名称值都放到这个字典中。
6、将函数存储在模块中
再将模块导入到主程序中,import语句允许在当前运行的程序文件中使用模块中代码。
导入整个模块
先创建模块(扩展名为.py的文件)pizza.py
def make_pizza(size, *toppings):
"""Summarize the pizza we are about to make."""
print("\nMaking a " + str(size) +
"-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
另一个py文件:
import pizza
make_pizza(16, 'pepperoni')
make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')
导入函数中的所有函数
使用* 无需使用句点表示法
from pizza import *
使用as给函数指定别名
别名:函数的另一个名称
from pizza import make_pizza as mp
导入特定的函数
from module_name import function_name
就可以不用pizza.make这样的格式
还可以通过逗号分隔函数名,导入任意数的函数
7、函数编写指南
只在其中使用小写字母和下划线。
第九章 类
1、创建和使用类
class Dog():
"""A simple attempt to model a dog."""
def __init__(self, name, age):
"""Initialize name and age attributes."""
self.name = name
self.age = age
def sit(self):
"""Simulate a dog sitting in response to a command."""
print(self.name.title() + " is now sitting.")
def roll_over(self):
"""Simulate rolling over in response to a command."""
print(self.name.title() + " rolled over!")
首字母大写为类,此处定义了一个名为Dog的类
__init__()称为方法
self, name, age 为三个形参,python自动传入实参self,每个与实例相关联的方法调用都自动传递实参self,它是一个指向实例本身的引用,让实例能够访问类中的属性和方法。
self会自动传递,因此不需要传递它。
根据类创建实例
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.")
my_dog为小写的名称,指根据类创建的实例
my_dog.name 指的是访问属性
Dog类引用这个属性时,使用的是self.name
调用方法:
可指定实例的名称,和要调用的方法并用句点分割。
my_dog = Dog('Willie', 6)
my_dog.sit()
my_dog.roll_over()
2、使用类和实例
给属性指定默认值
class Car:
"""A simple attempt to represent a car."""
def __init__(self, make, model, year):
"""Initialize attributes to describe a car."""
self.make = make
self.model = model
self.year = year
self.odometer_reading = 0
修改属性的值
有三种方式
①直接通过实例进行修改
my_dog.age = 23
②通过方法修改属性的值
def update_odometer(self.mileage):
self.odometer_reading = mileage
my_new_car.update_odometer(23)
③通过方法对属性的值进行递增
def increment_odometer(self,miles):
self.odometer_reading += miles
3、继承
类并非总要从0开始写,可以继承另一个类,自动获得另一个类的所有属性和方法。
原有的类称为父类,而新的类称为子类。
子类继承了父类的所有属性和方法,同时还可以定义自己的属性和方法。
子类的方法__init__( )
class ElectricCar(Car):
"""Represent aspects of a car, specific to electric vehicles."""
def __init__(self, make, model, year):
"""
Initialize attributes of the parent class.
Then initialize attributes specific to an electric car.
"""
super().__init__(make, model, year)
my_tesla = ElectricCar('tesla', 'model s', 2019)
print(my_tesla.get_descriptive_name())
supper( )
super()是一个特殊函数,让你能够调用父类(car)的方法。
此行让python调用Car类的方法__init__() , 让ElectricCar 实例包含这个方法中定义的所有属性,父性也称超类,super从此而来。
给子类定义属性和方法
class ElectricCar(Car):
"""Represent aspects of a car, specific to electric vehicles."""
def __init__(self, make, model, year):
"""
Initialize attributes of the parent class.
Then initialize attributes specific to an electric car.
"""
super().__init__(make, model, year)
self.battery_size = 75
def describe_battery(self):
"""Print a statement describing the battery size."""
print(f"This car has a {self.battery_size}-kWh battery.")
my_tesla.describe_battery()
重写父类的方法
可在子类中定义一个与要重写的父类方法同名的方法
class ElectricCar(Car):
#--ship--
def fill_gas_tank(self):
print('')
调用方法fill_gas_tank(),python忽略car类的方法
将实例用作属性
将类的一部分提取出来,作为一个独立的类。
可以将大型类拆分成多个协同工作的小类。
class Battery:
"""A simple attempt to model a battery for an electric car."""
def __init__(self, battery_size=75):
"""Initialize the battery's attributes."""
self.battery_size = battery_size
def describe_battery(self):
"""Print a statement describing the battery size."""
print(f"This car has a {self.battery_size}-kWh battery.")
def get_range(self):
"""Print a statement about the range this battery provides."""
if self.battery_size == 75:
range = 260
elif self.battery_size == 100:
range = 315
print(f"This car can go about {range} miles on a full charge.")
class ElectricCar(Car):
"""Represent aspects of a car, specific to electric vehicles."""
def __init__(self, make, model, year):
"""
Initialize attributes of the parent class.
Then initialize attributes specific to an electric car.
"""
super().__init__(make, model, year)
self.battery = Battery()
my_tesla = ElectricCar('tesla', 'model s', 2019)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
Battery没有继承任何类,ElectricCar类中添加了一个名为self.battery的属性。这行代码让python常见一个新的battery实例。
4、导入类
将类存储在模块中,然后在主程序中导入所需的模块
导入单个类
from car import Car
在一个模块中导入多个类
from car import Car , ElectricCar
导入整个模块
import car
导入模块中导入另一个模块
from module_name import *
使用别名
from electric_car import ElectricCar as Ec
python标准库
模块random中的randint()将两个整数作为参数,并随机返回一份位于两整数之间的整数。
choice()将一个列表或元组作为参数,并随机返回其中的一个元素。
第十章 文件和异常
1、从文件中读取数据
读取整个文件
先要打开文件open()只能接受一个参数,要打开文件的名称。
with open('pi_digits.txt') as file_object:
contents = file_object.read()
print(contents)
with在不需要访问文件后将其关闭。(由python确定关掉时间)
也可以调用open()和close()来打开和关闭文件,但是如果程序存在bug导致方法close()未执行,文件将不会关闭。
read()读取这个文件的全部内容,并将其作为一个长长的字符串赋给变量contents.
但是read()返回会多一个空字符串,即输出末尾多一个空行。
要删掉空行,可在函数调用中print()中使用rstrip()
print(contents.rstrip())
文件路径
在打开不在程序文件所属目录中的文件。
with open('test_files/filename.txt') as file_object:
注意:显示文件路径时,windows用反斜杠(\)而不是斜杠(/),但是代码中仍可以使用斜杠(/)
file_path = '/home/ehmatthes/other_files/test_files/filename.txt'
with open(file_path) as file_object:
逐行读取
对文本对象使用for循环
filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line)
若不要空格则:
print(line.rstrip())
去掉了右边的空格,两边则用strip()
创建一个包含文件各行内容的列表
即在with代码块外访问文件的内容
filename = 'pi_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
for line in lines:
print(line.rstrip())
readlines()从文件中读取每一行,并将其存储在一个列表中。
使用文件的内容
filename = 'pi_million_digits.txt'
with open(filename) as file_object:
lines = file_object.readlines()
pi_string = ''
for line in lines:
pi_string += line.strip()
print(pi_string)
print(len(pi_string))
注意:从文本中读取时,所有文本读为字符串,若读取的是数,并要用作数值,则必须用函数int(),或float()将其转换为浮点数。
检查字符串是否包括
for line in lines:
pi_string += line.strip()
birthday = input("Enter your birthday, in the form mmddyy: ")
if birthday in pi_string:
print("Your birthday appears in the first million digits of pi!")
else:
print("Your birthday does not appear in the first million digits of pi.")
2、写入文件
写入空文件
filename = 'programming.txt'
with open(filename, 'w') as file_object:
file_object.write("I also love finding meaning in large datasets.\n")
file_object.write("I love creating apps that can run in a browser.\n")
'w'表示写入模式
'a'表示附加模式
'r+'表示读写模式
'r'读取模式
若写入的文件不存在,函数open()将自动创建它
若用'w'打开文件时,该文件已存在,python将在返回文件对象前清空改文件的内容。(把原来写的东西清空)
注意:python只能将字符串写入文本文件
写入多行
write()不会在写入的文本末尾添加换行符,需要write()中包含换行符。
添加到文件
'a'模式将内容附加到文件末尾,而不是覆盖文件原来的内容。
3、异常
处理ZeroDivisionError异常
像使用5/0,就会报错。
使用try-except代码块
try:
print(5/0)
except ZeroDivisionError:
print("you can't divide by zero")
使用异常避免崩溃
提示用户提供有效输入,而不至于崩溃。
else代码块
try-except-else代码块
try:
answer = int(first_number)/int(second_number)
except ZeroDivisionError:
print("you can't ...zero")
else:
print(answer)
分析文本
split()可根据一个字符串创造一个单词列表。
以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。
filename = 'alice.txt'
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
print(f"Sorry, the file {filename} does not exist.")
else:
# Count the approximate number of words in the file.
words = contents.split()
num_words = len(words)
print(f"The file {filename} has about {num_words} words.")
使用多个文件
定义函数用来分析文件
可用循环从文件名称列表中进行依次调用
静默失败
在except代码块中明确告诉python什么都不要做
使用pass 语句
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
pass
4、存储数据
使用模块json来存储数据
模块json可以让你把简单的python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。还可用于python间的分享数据。
使用json.dump()和json.load()
函数json.dump()接受两个实参:要存储的数据,文件对象。
import json
numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json'
with open(filename, 'w') as f:
json.dump(numbers, f)
将数字列表存到numbers.json中了
若使用json.load()则:
import json
filename = 'username.json'
with open(filename) as f:
username = json.load(f)
print(f"Welcome back, {username}!")
username = json.load(f)
将存储在numbers.json中的信息赋给变量username
保存和读取用户生成的数据
使用json.dump()和json.load()与try_except_else结合
import json
filename = 'username.json'
try:
with open(filename) as f:
username = json.load(f)
except FileNotFoundError:
username = input('What id your name?')
with open(filename,'w') as f:
json.dump(username,f)
print(f"we'll remenber you...{username}!")
else:
print(f'wlcome back,{username}!')
重构
将大部分逻辑放到一个或多个函数中
例如将上面改为
import json
def greet_user():
filename = 'username.json'
try:
with open(filename) as f:
username = json.load(f)
except FileNotFoundError:
username = input('What id your name?')
with open(filename,'w') as f:
json.dump(username,f)
print(f"we'll remenber you...{username}!")
else:
print(f'wlcome back,{username}!')
greet_user()
或者写成两个函数,然后一个内部调用另一个
第十一章 测试代码
1、测试函数
学习如何测试函数和类,并将知道改为项目编写多少个测试。(自动测试)
单元测试和测试用例
模块unittest提供了代码测试工具
①测试单元:用于核实函数的某个方面没有问题
②测试用例:是一组单元测试,它们一道核实函数在各种情性下的行为都符合要求。
③可以全覆盖的测试,但对大型项目,通常,最初只要针对代码的重要行为编写测试即可。
可通过的测试
要为函数编写测试用例,可先导入模块unittest和要测试的函数,再创造一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。
import unittest #导入模块unittest
from name_function import get_formatted_name #要测试的函数
class NamesTestCase(unittest.TestCase): #创建一个继承unittest.TestCase的类
"""Tests for 'name_function.py'."""
def test_first_last_name(self): #以test开头
"""Do names like 'Janis Joplin' work?"""
formatted_name = get_formatted_name('janis', 'joplin') #两个实参
self.assertEqual(formatted_name, 'Janis Joplin')
if __name__ == '__main__':
unittest.main()
assertEqual 为断言:核实得到的结果是否与期望的结果一致。
将formatted_name的值与后面字符串比较
运行后会显示有几个测试通过,用了多久和ok。
Ran 1 tests in 0.008s
OK
未通过的测试
会显示ERROR
添加新测试
在Class Names TestCase (unittest.TestCase)下加入def
方法名必须以test_打头。
2、测试类
各种断言方法
unittest.TwatCase类中提供了很多断言方法
①assertEqual(a,b) 核实 a == b
②assertNotEqual(a,b) 核实a !=b
③assertTrue(x) 核实X为True
④assertFalse(x) 核实x为False
⑤assertIn(item,list) 核实item在list中
⑥assertNotIn(item,list) 核实item不在list中
测试类
单个答案和多个答案的例子
方法setup()
之前每次测试都要把被测试的实例建立一次并创建答案,太繁琐用unittest.TestCase类包含的setup()只需要创建这些对象一次,就能在每个测试方法中使用。
若:TestCase类中包含了方法setup(),python将先运行它,再运行各个以test_打头的方法。
即
Class TestAnonymous Survey (unittest.TestCase):
def setup(self):
question = ..
self.my_survey = ...
self.responses = ...
def test_store_single_response(self)