Python自动化测试笔记

 

目录

 

1.Python中的标识符(变量,类,方法等取的名字)

2.python中的关键字

 3.python中的注释方法

4.Python行与缩进

5.多行语句

6.python中的基础数据类型

7.python中输入和输出的方法

8.python中的运算符

9.列表

9.0.1 在列表中添加元素

9.0.2 列表中弹出元素

9.0.3 列表中排序的方法

9.0.4 反转打印列表

9.0.5 确定列表的长度

9.0.6 列表的切片

10.元组

10.0.1 定义元组:

10.0.2 遍历元组中的所有值

10.0.3 修改元组中的值

11.if语句

11.0.1同时检查多个条件

12.字典

12.0.1嵌套

13.用户输入和while 循环

14.使用while 循环来处理列表和字典

15.定义函数

 

15.0.1 位置实参

15.0.2 关键字实参

15.0.3 默认值

15.0.4 等效的函数调用

15.0.5 返回值

15.0.6 让实参变成可选的

15.0.7 返回字典

15.0.8 传递列表

15.0.9 在函数中修改列表

15.1.0 禁止函数修改列表

15.1.1 传递任意数量的实参

15.1.2 结合使用位置实参和任意数量实参

15.1.3 使用任意数量的关键字实参

15.1.4 将函数存储在模块中

15.1.5 使用as 给函数指定别名

15.1.6 使用as 给模块指定别名

15.1.7 导入模块中的所有函数

16.类

16.0.1 根据类创建实例

16.0.2 使用类和实例

16.0.3 给属性指定默认值

16.0.4 修改属性的值

17.继承

17.0.1 子类的方法__init__()

17.0.2 给子类定义属性和方法

17.0.3 重写父类的方法

17.0.4 将实例用作属性

17.0.5 导入类

17.0.6 Python标准库

18.文件和异常

18.1 从文件中读取数据

18.1.1 读取整个文件

18.1.2 文件路径

18.1.3 逐行读取

18.1.4 创建一个包含文件各行内容的列表

18.1.5 使用文件的内容

18.1.6 包含一百万位的大型文件

18.2 写入文件

18.2.1 写入空文件

18.2.2 写入多行

18.2.3 附加到文件

18.3 异常

18.3.1 处理ZeroDivisionError 异常

18.3.2 使用try-except 代码块

18.3.3 使用异常避免崩溃

18.3.4 else 代码块

18.3.5 处理FileNotFoundError 异常

18.3.6 分析文本

18.3.7 使用多个文件


1.Python中的标识符(变量,类,方法等取的名字)

1.1必须是字母,数字或者下划线组成 

1.2数字不能开头

1.3对大小写敏感(区分大小写)true与True

age=20   _age=20   

2.python中的关键字

'False', 'None', 'True', 'and', 
'as', 'assert', 'async', 'await',
 'break', 'class', 'continue', 'def',
 'del', 'elif', 'else', 'except', 'finally', 
'for', 'from', 'global', 'if', 'import',
 'in', 'is', 'lambda', 'nonlocal', 'not', 
'or', 'pass', 'raise', 'return', 'try', 
'while', 'with', 'yield']

 3.python中的注释方法

age=10 #单行注释


'''age=10
aa=10
'''多行注释

4.Python行与缩进

a=10
b=20
def sum(a,b):
    return a+b#符合要求
return a+b#不符合要求
print(sum(10,20))

5.多行语句

长语句以 \来实现多行语句
toal=item_one+\
     item_two\
     item_three

如果语句中包括{}[]或者()就不需要使用多行连接符号
toal=['a','c']

6.python中的基础数据类型

python中一切皆对象(类)
数字类型:整形,浮点型,复数类型,布尔
字符串:定义字符串可以单引号 双引号定义  a='cc' b="cc" 
多行字符 使用三个单引号
转义符 "abc\n" \n回车换行 
自然字符串:不包括带有转义功能的元字符()使用R,r来表示
r"你好你好"
R"你好你好"
List(列表)
【List(列表) 是 Python 中使用最频繁的数据类型。

列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。

列表是写在方括号 [] 之间、用逗号分隔开的元素列表。

和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。】

list=[1,2,3]
Tuple(元组)
元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。

元组中的元素类型也可以不相同:tuple=(1,2,3)
虽然tuple的元素不可改变,但它可以包含可变的对象,比如list列表。

构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:

tup1 = ()    # 空元组
tup2 = (20,) # 一个元素,需要在元素后添加逗号
Set(集合)

Dictionary(字典)
字典(dictionary)是Python中另一个非常有用的内置数据类型。

列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。

字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合。

键(key)必须使用不可变类型。

在同一个字典中,键(key)必须是唯一的。dict={}

7.python中输入和输出的方法

输入 input 
age=input('请输入你的年龄:')
age1=int(age)#类型的转换
print("我的年龄是:%s" %age1)


输出print 

print('我的名字是:%r,年龄是:%r'(name,age)) %r可以代表任意数据类型 %s 字符串 %d数字

8.python中的运算符

 基础运算符:::::
+	加 - 两个对象相加	a + b 输出结果 31
-	减 - 得到负数或是一个数减去另一个数	a - b 输出结果 -11
*	乘 - 两个数相乘或是返回一个被重复若干次的字符串	a * b 输出结果 210
/	除 - x 除以 y	b / a 输出结果 2.1
%	取模 - 返回除法的余数	b % a 输出结果 1
**	幂 - 返回x的y次幂	a**b 为10的21次方
//	取整除 - 向下取接近商的整数	
>>> 9//2
4
>>> -9//2
-5

比较运算符
==	等于 - 比较对象是否相等	(a == b) 返回 False。
!=	不等于 - 比较两个对象是否不相等	(a != b) 返回 True。
>	大于 - 返回x是否大于y	(a > b) 返回 False。
<	小于 - 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。	(a < b) 返回 True。
>=	大于等于 - 返回x是否大于等于y。	(a >= b) 返回 False。
<=	小于等于 - 返回x是否小于等于y。	(a <= b) 返回 True。

赋值运算符
=	简单的赋值运算符	c = a + b 将 a + b 的运算结果赋值为 c
+=	加法赋值运算符	c += a 等效于 c = c + a
-=	减法赋值运算符	c -= a 等效于 c = c - a
*=	乘法赋值运算符	c *= a 等效于 c = c * a
/=	除法赋值运算符	c /= a 等效于 c = c / a
%=	取模赋值运算符	c %= a 等效于 c = c % a
**=	幂赋值运算符	c **= a 等效于 c = c ** a
//=	取整除赋值运算符	c //= a 等效于 c = c // a
:=	海象运算符,可在表达式内部为变量赋值。Python3.8 版本新增运算符。	
在这个示例中,赋值表达式可以避免调用 len() 两次:

if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

9.列表

9.0.1 在列表中添加元素

方法append() 将元素'ducati' 添加到了列表末尾

使用方法:str.append('nannaan')

使用方法insert() 可在列表的任何位置添加新元素。为此,你需要指定新元素的索引和值。

motorcycles.insert(0, 'ducati')

9.0.2 列表中弹出元素

在列表中弹出元素进行处理pop() :

namelist=['a1','a2','a']
namepop=namelist.pop()#默认弹出末尾的值 从列表删除后依然可以弹出使用
print(namepop)#

9.0.3 列表中排序的方法

Python方法sort() 让你能够较为轻松地对列表进行排序 :按字母顺序排列。

只需向sort() 方法传递参数reverse=True:按字母顺序反方向排序

要保留列表元素原来的排列顺序,同时以特定的顺序呈现它们,可使用函数sorted() 。函数sorted() 让你能够按特定顺序显示列表元素,同时不影响它们在列表中的原始排 列顺序。

9.0.4 反转打印列表

要反转列表元素的排列顺序,可使用方法reverse():reverse() 不是指按与字母顺序相反的顺序排列列表元素,而只是反转列表元素的排列顺序:

9.0.5 确定列表的长度

使用函数len() 可快速获悉列表的长度

9.0.6 列表的切片

cslist=['a','b','c']
for cs in cslist[:2]:#遍历输出切片
    print(cs)
print(cslist[2:3])#切片输出
cs2list=cslist[:]#复制整个列表
cs2list.append('d')#复制的列表中添加元素
print(cs2list)'''

10.元组

Python将不能修改的值称为不可变的 ,而不可变的列表被称为元组

10.0.1 定义元组:

用()来表示,。定义元组后,就可以使用索引来访问其元素,就像访问列表元素一样。

dimensions = (200, 50)#定义元组
print(dimensions[0])#输出元组第一个数据
print(dimensions[1])

10.0.2 遍历元组中的所有值

dimensions = (200, 50)#定义元组
print("遍历元组:")
for dimension in dimensions:#元组的遍历
    print(dimension)

10.0.3 修改元组中的值

相当于给元组重新赋值
dimensions = (200, 50)#定义元组
print("遍历元组:")
for dimension in dimensions:#元组的遍历
    print(dimension)
dimensions=(400,100)
print("\n修改元组变量")
for dimension in dimensions:
    print(dimension)

11.if语句

每条if 语句的核心都是一个值为True 或False 的表达式,这种表达式被称为条件测试 。Python根据条件测试的值为True 还是False 来决定是否执行if 语句中的代码。如果 条件测试的值为True ,Python就执行紧跟在if 语句后面的代码;如果为False ,Python就忽略这些代码。
 

age=18
if age>=18:
    print("已成年")
else:
    print("未成年")

11.0.1同时检查多个条件

 

and :当有一个条件不满足时返回false  满足2个条件才返回ture

or:满足任意一个条件返回ture 2个条件都不相等时返回false

in:

if 'a' in cslist:#判断在不在列表中

not in:检查不在列表中


12.字典

zidian={'key':'value'}

'''zidian={}
zidian['a']=1
zidian['b']=2
zidian['a']=20
print(zidian)
del zidian['a']
print(zidian)'''
#遍历字典中的数据

'''user_0 = {
'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
for key,value in user_0.items():#将遍历的它返回一个键—值对列表
    print("\nKey:"+key)
    print("Value:"+value)'''
'''favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
friends = ['phil', 'sarah']
for name in favorite_languages.keys():
    print(name.title())
    if name in friends:
        print(" Hi " + name.title() +
", I see your favorite language is " + favorite_languages[name].title() + "!")
'''
'''favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
for language in set(favorite_languages.values()):#使用集合去重复保证值的独一无二
    print(language.title())

for name in sorted(favorite_languages.keys()):#顺序排序遍历字典中的键
    print(name)'''

12.0.1嵌套

字典中可以嵌套列表

izza = {
'crust': 'thick',
'toppings': ['mushrooms', 'extra cheese'],
}
for pizzas in pizza['toppings']:#遍历字典中的列表
    print(pizzas)'''

字典中也可以嵌套字典

users = {
'aeinstein': {
'first': 'albert',
'last': 'einstein',
'location': 'princeton',
},
'mcurie': {
'first': 'marie',
'last': 'curie',
'location': 'paris',
},
}
for username, user_info in users.items():#循环遍历键和值 存在在变量username, user_info中
    print("\nUsername: " + username)#输出键
    full_name = user_info['first'] + " " + user_info['last']#定义变量 full_name,其中包含user_info['first']user_info['last']的值
    location = user_info['location']#定义变量包含user_info['location']的值
print("\tFull name: " + full_name.title())
print("\tLocation: " + location.title())'''

13.用户输入和while 循环

用户输入采用input()方法

message = input("Tell me something, and I will repeat it back to you: ")#可以增加提示信息让用户输入
print(message)

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

pj=input("请输入你的年龄:")
pj=int(pj)
while pj:#循环用户输入
    if pj <= 3:#对用户输入进行判断
        print('免费')
        break
    elif pj<=12:
        print('10元')
        break
    else:
        print('12元')
        break

14.使用while 循环来处理列表和字典

yz_users=['long','he','liu']#创建一个待验证的列表
yzcg_users=[]#创建一个存放验证过了的列表
while yz_users:#循环验证待验证列表
    yz_user=yz_users.pop()#每次循环验证 都弹出该用户
    print('验证的用户名为:'+yz_user)
    yzcg_users.append(yz_user)#验证后添加到空列表中
print("显示所有已验证的用户:")
for yzcg_user in yzcg_users:#遍历已经验证的用户
    print(yzcg_user.title())

想让循环一直以ture运行可以设置一个标值 当标值为ture时 whlie 循环会一直运行 直到标值为false  :biaozhi=Ture 

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 == 'no':
        polling_active = False
# 调查结束,显示结果
print("\n--- Poll Results ---")
for name, response in responses.items():
    print(name + " would like to climb " + response + ".")

删除包含特定值的所有列表元素:我们使用函数remove() 来删除列表中的特定值:

dongwu=['cat','dog','mokeny','cat']
print(dongwu)
while 'cat' in dongwu:
    dongwu.remove('cat')
print(dongwu)

15.定义函数

def user_cs(username):###username是形参
    print('hello')
user_cs('kall')#实参'''

 

15.0.1 位置实参

最简单的关联方式是基于实参的顺序。这种关联方式被称为位置实参 。

def describe_pet(animal_type, pet_name):
"""显示宠物的信息"""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet('hamster', 'harry')#形参的位置对应实参

15.0.2 关键字实参

关键字实参 是传递给函数的名称—值对。你直接在实参中将名称和值关联起来了

def describe_pet(animal_type, pet_name):
"""显示宠物的信息"""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet(animal_type='hamster', pet_name='harry')#值对应

15.0.3 默认值

编写函数时,可给每个形参指定默认值 。在调用函数中给形参提供了实参时,Python将使用指定的实参值;否则,将使用形参的默认值。

def describe_pet(pet_name, animal_type='dog'):
"""显示宠物的信息"""
print("\nI have a " + animal_type + ".")
print("My " + animal_type + "'s name is " + pet_name.title() + ".")
describe_pet(pet_name='willie')

15.0.4 等效的函数调用

鉴于可混合使用位置实参、关键字实参和默认值,通常有多种等效的函数调用方式

# 一条名为Willie的小狗
describe_pet('willie')
describe_pet(pet_name='willie')
# 一只名为Harry的仓鼠
describe_pet('harry', 'hamster')
describe_pet(pet_name='harry', animal_type='hamster')
describe_pet(animal_type='hamster', pet_name='harry')

15.0.5 返回值

函数并非总是直接显示输出,相反,它可以处理一些数据,并返回一个或一组值。函数返回的值被称为返回值 。

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)

调用返回值的函数时,需要提供一个变量,用于存储返回的值。

15.0.6 让实参变成可选的

有时候,需要让实参变成可选的,这样使用函数的人就只需在必要时才提供额外的信息。可使用默认值来让实参变成可选的。

def get_name(first_name, last_name, mid_name=''):
    if mid_name:#判断mid_name为ture也就是有数据
        full_name=first_name+' '+mid_name+' '+last_name
    else:
        full_name=first_name+' '+last_name
     return full_name#将值返回导函数
name=get_name('long','wen','jie')
print(name)
names=get_name('long','wenjie')
print(names)

15.0.7 返回字典

函数可返回任何类型的值,包括列表和字典等较复杂的数据结构。

def user_name(first,last,age=''):
    name={'firstname':first,'lastname':last}#定义函数值所在的字典
    if age:#判断age是否为ture
        name['age']=age#如果输入了age则赋值到name['age']封装到字典
    return name
names=user_name('long','wenjie',age=18)
print(names)

15.0.8 传递列表

将列表传递给函数后,函数就能直接访问其内容。

def get_name(names):#定义一个函数包含形参
    for name in names:遍历参数
        msg='hello,'+name.title()
        print(msg)
user_name=['long','wen','jie']#定义一个列表
get_name(user_name)#调用函数方法 循环遍历列表的值

15.0.9 在函数中修改列表

将列表传递给函数后,函数就可对其进行修改。

def print_models(unprinted_designs,completed_models):
    """ 模拟打印每个设计,直到没有未打印的设计为止
    打印每个设计后,都将其移到列表completed_models中
    """
    while unprinted_designs:
        current_design = unprinted_designs.pop()
        print('打印的模型为:'+current_design)
        completed_models.append(current_design)
def show_completed_models(completed_models):
    """显示打印好的所有模型"""
    print('\n打印好的模型为:')
    for completed_model in completed_models:
        print(completed_model)
unprinted_designs = ['iphone case', 'robot pendant', 'dodecahedron']
completed_models = []
print_models(unprinted_designs, completed_models)
show_completed_models(completed_models)

15.1.0 禁止函数修改列表

为解决这个问题,可向函数传递列表的副本而不是原件

要将列表的副本传递给函数,可以像下面这样做:function_name(list_name[:])

 

15.1.1 传递任意数量的实参

有时候,你预先不知道函数需要接受多少个实参,好在Python允许函数从调用语句中收集任意数量的实参。

def make_pizza(*toppings):######*toppings但不管调用语句提供了多少实参,这个
形参都将它们统统收入囊中:

"""打印顾客点的所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')

不管收到的是一个值还是三个值,这个函数都能妥善地处理

 

15.1.2 结合使用位置实参和任意数量实参

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

def make_pizza(size, *toppings):
    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')

 

15.1.3 使用任意数量的关键字实参

有时候,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。在这种情况下,可将函数编写成能够接受任意数量的键—值对——调用语句提供了多少就接 受多少。

def build_profile(first,last,**user_info):#两个星号让Python创建一个名为user_info 的空字典,并将收到的所有名称—值对都封装到这个字典中。
    profile={}#我们创建了一个名为profile 的空字典,用于存储用户简介
    profile['first_name']=first#字典中的key 对应的vlue
    profile['last_name']=last
    for k,y in user_info.items():#遍历字典
        profile[k]=y#并将每个键—值对都加入到字典profile 中。
        return profile
user_profile = build_profile('albert', 'einstein',
location='princeton',
field='physics')
print(user_profile

15.1.4 将函数存储在模块中

函数的优点之一是,使用它们可将代码块与主程序分离。通过给函数指定描述性名称,可让主程序容易理解得多。你还可以更进一步,将函数存储在被称为模块 的独立文件中, 再将模块导入 到主程序中。import 语句允许在当前运行的程序文件中使用模块中的代码。

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

创建一个 pizz.py的文件 里面包含函数:

def make_pizzas(*fulls):
    print('添加的配料:')
    for full in fulls:
        print(full)
def cars_name(name,pinp,**full):
    car={}
    car['name']=name
    car['pinp']=pinp
    for k,y in full.items():
        car[k]=y
    return car

然后进行导入使用

import pizz
pizz.make_pizzas('火腿肠','鸡蛋')

导入特定的函数:

from  pizz import cars_name 
user= cars_name('本田','跑车',color='blue',css=100)
print(user)

15.1.5 使用as 给函数指定别名

如果要导入的函数的名称可能与程序中现有的名称冲突,或者函数的名称太长,可指定简短而独一无二的别名 ——函数的另一个名称,类似于外号。要给函数指定这种特殊外 号,需要在导入它时这样做。

from  pizz import cars_name as car
user= cars_name('本田','跑车',color='blue',css=100)
print(user)

15.1.6 使用as 给模块指定别名

import pizz as p
pizz.make_pizzas('火腿肠','鸡蛋')

15.1.7 导入模块中的所有函数

使用星号(* )运算符可让Python导入模块中的所有函数

 

from  pizz import *
user= cars_name('本田','跑车',color='blue',css=100)
print(user)

16.类

根据类来创建对象被称为实例化 ,根据Dog 类创建的每个实例都将存储名字和年龄。我们赋予了每条小狗蹲下(sit() )和打滚(roll_over() )的能力:

class Dog():
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def sit(self):
        print(self.name.title()+'is now sitting')
    def roll_over(self):
        print(self.name.title()+'rolled over!')

. 1.方法__init__()类中的函数称为方法

16.0.1 根据类创建实例

class Dog():
--snip--
my_dog = Dog('willie', 6)###实例化对象
print("My dog's name is " + my_dog.name.title() + ".") 
print("My dog is " + str(my_dog.age) + " years old.")

16.0.2 使用类和实例

你可以使用类来模拟现实世界中的很多情景。

class Car():
"""一次模拟汽车的简单尝试"""
def __init__(self, make, model, year):
"""初始化描述汽车的属性"""
self.make = make
self.model = model
self.year = year
def get_descriptive_name(self):
"""返回整洁的描述性信息"""
long_name = str(self.year) + ' ' + self.make + ' ' + self.model
return long_name.title()
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())

16.0.3 给属性指定默认值

类中的每个属性都必须有初始值,哪怕这个值是0或空字符串。在有些情况下,如设置默认值时,在方法__init__() 内指定这种初始值是可行的

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):
--snip--
def read_odometer(self):
"""打印一条指出汽车里程的消息"""
print("This car has " + str(self.odometer_reading) + " miles on it.")
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.read_odometer()

16.0.4 修改属性的值

可以以三种不同的方式修改属性的值:直接通过实例进行修改;通过方法进行设置;通过方法进行递增(增加特定的值)。

1. 直接修改属性的值:

class Car():
--snip--
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.odometer_reading = 23
my_new_car.read_odometer()

2. 通过方法修改属性的值:

class Car():
--snip--
def update_odometer(self, mileage):
"""将里程表读数设置为指定的值"""
self.odometer_reading = mileage
my_new_car = Car('audi', 'a4', 2016)
print(my_new_car.get_descriptive_name())
my_new_car.update_odometer(23)
my_new_car.read_odometer()

3. 通过方法对属性的值进行递增:

有时候需要将属性值递增特定的量,而不是将其设置为全新的值。

class Car():
--snip--
def update_odometer(self, mileage):
--snip--
def increment_odometer(self, miles):
"""将里程表读数增加指定的量"""
self.odometer_reading += miles
my_used_car = Car('subaru', 'outback', 2013)
print(my_used_car.get_descriptive_name())
my_used_car.update_odometer(23500)
my_used_car.read_odometer()
my_used_car.increment_odometer(100)
my_used_car.read_odometer()

17.继承

编写类时,并非总是要从空白开始。如果你要编写的类是另一个现成类的特殊版本,可使用继承 。一个类继承 另一个类时,它将自动获得另一个类的所有属性和方法;原有的 类称为父类 ,而新类称为子类 。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

17.0.1 子类的方法__init__()

创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法__init__() 需要父类施以援手。

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 = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()
    def read_odometer(self):
        print("This car has " + str(self.odometer_reading) + " miles on it.")
    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")
    def increment_odometer(self, miles):
        self.odometer_reading += miles


class ElectricCar(Car):###继承Car类的方法
    def __init__(self,make,model,year):#方法__init__() 接受创建Car 实例所需的信息
        super().__init__(make,model,year)#处的super() 是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用ElectricCar 的父类的方法__init__() ,让ElectricCar 实例包含父类的所有属性。
my_car=ElectricCar('testla','model','2020')
print(my_car.get_descriptive_name())

super() 是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用ElectricCar 的父类的方法__init__() ,让ElectricCar 实例包含父类的所 有属性。父类也称为超类 (superclass),名称super因此而得名。

17.0.2 给子类定义属性和方法

让一个类继承另一个类后,可添加区分子类和父类所需的新属性和方法。

class ElectricCar(Car):###继承Car类的方法
    def __init__(self,make,model,year):#方法__init__() 接受创建Car 实例所需的信息
        super().__init__(make,model,year)#处的super() 是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用ElectricCar 的父类的方法__init__() ,让ElectricCar 实例包含父类的所有属性。
        self.battery_size=100
    def describe_battery(self):#给子类定义一个新方法
        print('这个汽车的电池容量为:'+str(self.battery_size)+'千瓦')
my_car=ElectricCar('testla','model','2020')
print(my_car.get_descriptive_name())
my_car.describe_battery()

17.0.3 重写父类的方法

对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这 个父类方法,而只关注你在子类中定义的相应方法。

def ElectricCar(Car):
--snip--
def fill_gas_tank():
"""电动汽车没有油箱"""
print("This car doesn't need a gas tank!")

现在,如果有人对电动汽车调用方法fill_gas_tank() ,Python将忽略Car 类中的方法fill_gas_tank() ,转而运行上述代码。

 

17.0.4 将实例用作属性

使用代码模拟实物时,你可能会发现自己给类添加的细节越来越多:属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分作为一个独立的类提取出来。 你可以将大型类拆分成多个协同工作的小类。
 

class Car():
--snip--
class Battery():
"""一次模拟电动汽车电瓶的简单尝试"""
def __init__(self, battery_size=70):
"""初始化电瓶的属性"""
self.battery_size = battery_size
def describe_battery(self):
"""打印一条描述电瓶容量的消息"""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
class ElectricCar(Car):
"""电动汽车的独特之处"""
def __init__(self, make, model, year):
""" 初始化父类的属性,再初始化电动汽车特有的属性
"""
super().__init__(make, model, year) ❹ self.battery = Battery()
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()

17.0.5 导入类

 

随着你不断地给类添加功能,文件可能变得很长,即便你妥善地使用了继承亦如此。为遵循Python的总体理念,应让文件尽可能整洁。为在这方面提供帮助,Python允许你将类存 储在模块中,然后在主程序中导入所需的模块。

导入整个模块 import Car
导入指定类 from Car import ElectricCar
从一个模块导入多个类from car import Car, ElectricCar
导入所有类from module_name import *

17.0.6 Python标准库

Python标准库 是一组模块,安装的Python都包含它

 

from random import randint

class Die():
    def __init__(self,sides='6'):###初始化 筛子6个面
        self.sides=sides
    def roll_die(self):#定义一个方法
        for n in range(11):#循环10个数
            print(randint(1,eval(self.sides)),end=' ')
        print(' ')'''

18.文件和异常

18.1 从文件中读取数据

要使用文本文件中的信息,首先需要将信息读取到内存中。为此,你可以一次性读取文件的全部内容,也可以以每次一行的方式逐步读取。

18.1.1 读取整个文件

要读取文件,需要一个包含几行文本的文件。下面首先来创建一个文件,它包含精确到小数点后30位的圆周率值,且在小数点后每10位处都换行:

3.1415926535
8979323846
2643383279

下面的程序打开并读取这个文件,再将其内容显示到屏幕上:

#关键字with 在不再需要访问文件后将其关闭。
with open('pi_digits') as  file_object:#打开文件  函数open()接受参数为打开文件的名称 as  file_object返回在我们所设置的变量中
    contents=file_object.read()#使用read()方法读取数据并存放在contents变量中
    print(contents.rstrip())#rstrip()方法删除末尾的空行

18.1.2 文件路径

当你将类似pi_digits.txt这样的简单文件名传递给函数open() 时,Python将在当前执行的文件(即.py程序文件)所在的目录中查找文件。

要让Python打开不与程序文件位于同一个目录中的文件,需要提供文件路径 ,它让Python到系统的特定位置 去查找。

由于文件夹text_files位于文件夹python_work中,因此可使用相对文件路 径来打开该文件夹中的文件。相对文件路径让Python到指定的位置去查找,而该位置是相对于当前运行的程 序所在目录的。在Linux和OS X中,你可以这样编写代码:

with open('text_files/filename.txt') as file_object:
with open('txt_files/filename') as file_name:#使用绝对路径打开文件
    file_read=file_name.read()
    print(file_read.rstrip())

你还可以将文件在计算机中的准确位置告诉Python,这样就不用关心当前运行的程序存储在什么地方了。这称为绝对文件路径 。在相对路径行不通时,可使用绝对路径。

例如:打开计算机中的文件
 

open_file='D:/aaaa/admin/cs.txt'##读取电脑中的文件
with open(open_file) as bugtxt:
    txtread=bugtxt.read()
    print(txtread)

18.1.3 逐行读取

读取文件时,常常需要检查其中的每一行:你可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本。例如,你可能要遍历一个包含天气数据的文件,并使用天 气描述中包含字样sunny的行。在新闻报道中,你可能会查找包含标签 的行,并按特定的格式设置它。

要以每次一行的方式检查文件,可对文件对象使用for 循环:

filename = 'pi_digits.txt'
with open(filename) as file_object:
for line in file_object:
print(line.rstrip())

18.1.4 创建一个包含文件各行内容的列表

将文件读取到内存中后,就可以以任何方式使用这些数据了。下面以简单的方式使用圆周率的值。首先,我们将创建一个字符串,它包含文件中存储的所有数字,且没有任何空 格:

filename = 'pi_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines()
for line in lines:
    print(line.rstrip())

18.1.5 使用文件的内容

with open('pi_digits') as  file_object:#打开文件  函数open()接受参数为打开文件的名称 as  file_object返回在我们所设置的变量中
    contents=file_object.read()#使用read()方法读取数据并存放在contents变量中
    print(contents.rstrip())#rstrip()方法删除末尾的空行'''
pi_string=''#定义一个空变量
for line in contents:#遍历整个文件的值
    pi_string+=line.rstrip()#将遍历的行数 赋值给pi_string
print(pi_string)
print(len(pi_string))

读取文本文件时,Python将其中的所有文本都解读为字符串。如果你读取的是数字,并要将其作为数值使用,就必须使用函数int() 将其转换为整数,或使用 函数float() 将其转换为浮点数。

18.1.6 包含一百万位的大型文件

 

前面我们分析的都是一个只有三行的文本文件,但这些代码示例也可处理大得多的文件。如果我们有一个文本文件,其中包含精确到小数点后1 000 000位而不是30位的圆周率 值,也可创建一个包含所有这些数字的字符串。

file_read='txt_files/filename'
with open(file_read) as file_object:#打开文件
    lines=file_object.read()#读取文本
pi_string=''
for line in lines:#遍历数据
    pi_string+=line.strip()#清除空行后将数据存储在pi_string中
print(pi_string[:52])#输出前52位
print(len(pi_string))

18.2 写入文件

保存数据的最简单的方式之一是将其写入到文件中。通过将输出写入文件,即便关闭包含程序输出的终端窗口,这些输出也依然存在:你可以在程序结束运行后查看这些输出, 可与别人分享输出文件,还可编写程序来将这些输出读取到内存中并进行处理。

18.2.1 写入空文件

要将文本写入文件,你在调用open() 时需要提供另一个实参,告诉Python你要写入打开的文件。为明白其中的工作原理,我们来将一条简单的消息存储到文件中,而不是将其打 印到屏幕上:

filename='pi_digits'
with open(filename,'w') as file_object:#第二个实参('w' )告诉Python,我们要以写入模式 打开这个文件。
    file_object.write("i love her")#使用写入方法write()

可指定读取模式 ('r' )、写入模式 ('w' )、附加模式 ('a' )或让你能够读取和写入文件的模式('r+' )。如果你省略了模式实参,Python将以默认的只读模式打 开文件。

18.2.2 写入多行

函数write() 不会在你写入的文本末尾添加换行符,因此如果你写入多行时没有指定换行符,文件看起来可能不是你希望的那样:

filename='pi_digits'
with open(filename,'w') as file_object:#第二个实参('w' )告诉Python,我们要以写入模式 打开这个文件。
    file_object.write("i love he\n")#使用写入方法write()
    file_object.write('i love creating new games\n')#要让每个字符串都单独占一行,需要在write() 语句中包含换行符:

18.2.3 附加到文件

如果你要给文件添加内容,而不是覆盖原有的内容,可以附加模式 打开文件。你以附加模式打开文件时,Python不会在返回文件对象前清空文件,而你写入到文件的行都将添加 到文件末尾。如果指定的文件不存在,Python将为你创建一个空文件。

filename='pi_digits'
with open(filename,'a') as file_object:#'a'为附加方法 不会清空文件
    file_object.write('I also love read books\n')
    file_object.write('I very like eat ice\n')

18.3 异常

Python使用被称为异常 的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继 续运行;如果你未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。

18.3.1 处理ZeroDivisionError 异常

print(5/0)#输出

Traceback (most recent call last):
File "division.py", line 1, in <module>
print(5/0)  
ZeroDivisionError: division by zero########发生异常

18.3.2 使用try-except 代码块

当你认为可能发生了错误时,可编写一个try-except 代码块来处理可能引发的异常。你让Python尝试运行一些代码,并告诉它如果这些代码引发了指定的异常,该怎么办。

try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
#如果成功则运行try 中代码
如果失败运行 except中的代码

18.3.3 使用异常避免崩溃

发生错误时,如果程序还有工作没有完成,妥善地处理错误就尤其重要。这种情况经常会出现在要求用户提供输入的程序中;如果程序能够妥善地处理无效输入,就能再提示用 户提供有效输入,而不至于崩溃。

print('请输入2个数字!')
print('输入q退出')
while True:
    first_number=input('请输入第一个数字:')
    if first_number=='q':
        break
    sencond_number=input('请输入第二个数字:')
    if sencond_number=='q':
        break
    answer=int(first_number)/int(sencond_number)
    print(answer)

在❶处,这个程序提示用户输入一个数字,并将其存储到变量first_number 中;如果用户输入的不是表示退出的q,就再提示用户输入一个数字,并将其存储到变 量second_number 中(见❷)。接下来,我们计算这两个数字的商(即answer ,见❸)。这个程序没有采取任何处理错误的措施,因此让它执行除数为0的除法运算时,它 将崩溃:

 

18.3.4 else 代码块

通过将可能引发错误的代码放在try-except 代码块中,可提高这个程序抵御错误的能力。错误是执行除法运算的代码行导致的,因此我们需要将它放到try-except 代码块 中。这个示例还包含一个else 代码块;依赖于try 代码块成功执行的代码都应放到else 代码块中:

print('请输入2个数字!')
print('输入q退出')
while True:
    first_number=input('请输入第一个数字:')
    if first_number=='q':
        break
    sencond_number=input('请输入第二个数字:')
    if sencond_number=='q':
        break
    try:
        anser=int(first_number)/int(sencond_number)
    except ZeroDivisionError:
        print('您不能除以0!')
    else:
        print(anser)

try-except-else 代码块的工作原理大致如下:Python尝试执行try 代码块中的代码;只有可能引发异常的代码才需要放在try 语句中。有时候,有一些仅在try 代码块成功 执行时才需要运行的代码;这些代码应放在else 代码块中。except 代码块告诉Python,如果它尝试运行try 代码块中的代码时引发了指定的异常,该怎么办。

18.3.5 处理FileNotFoundError 异常

使用文件时,一种常见的问题是找不到文件:你要查找的文件可能在其他地方、文件名可能不正确或者这个文件根本就不存在。对于所有这些情形,都可使用try-except 代码 块以直观的方式进行处理。

filename='aaa'
try:
    with open(filename) as file_l:
        aa=file_l.read()
except FileNotFoundError:
    msg='sorry,the file'+filename+'不存在'
    print(msg)

在这个示例中,try 代码块引发FileNotFoundError 异常,因此Python找出与该错误匹配的except 代码块,并运行其中的代码。最终的结果是显示一条友好的错误消息,而 不是traceback:

 

18.3.6 分析文本

你可以分析包含整本书的文本文件。

 

下面来提取童话 Alicein Wonderland 的文本,并尝试计算它包含多少个单词。我们将使用方法split() ,它根据一个字符串创建一个单词列表。

file_name='pi_digit'
try:
    with open(file_name,'rb') as file_book:#打开文件
        js=file_book.read()#读取文件
except FileNotFoundError:
    msg='sorry,the file'+file_name+'不存在'#错误提醒
else:
    words=js.split()#方法split() 以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。
    new_words=len(words)#计算words的长度
    print('文本 '+file_name+'大概有 '+str(new_words)+'个字')

18.3.7 使用多个文件

下面多分析几本书。这样做之前,我们先将这个程序的大部分代码移到一个名为count_words() 的函数中,这样对多本书进行分析时将更容易:

def count_book(filename):
    try:
        with open(filename,'rb') as file_name:
            contents=file_name.read()
    except FileNotFoundError:
        msg='sorry,the file'+filename+'不存在'#错误提醒
    else:
        words = contents.split()  # 方法split() 以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。
        new_words = len(words)  # 计算words的长度
        print('文本 ' + filename + '大概有 ' + str(new_words) + '个字')

filename=['pi_digit','pi_digits']
for files in filename:#遍历列表的文件名称
    count_book(files)

18.3.8 失败时一声不吭

在前一个示例中,我们告诉用户有一个文件找不到。但并非每次捕获到异常时都需要告诉用户,有时候你希望程序在发生异常时一声不吭,就像什么都没有发生一样继续运行

def count_book(filename):
    try:
        with open(filename,'rb') as file_name:
            contents=file_name.read()
    except FileNotFoundError:
        pass#出现错误后之间跳过
    else:
        words = contents.split()  # 方法split() 以空格为分隔符将字符串分拆成多个部分,并将这些部分都存储到一个列表中。
        new_words = len(words)  # 计算words的长度
        print('文本 ' + filename + '大概有 ' + str(new_words) + '个字')
filename=['ccc','bbb']
for filenames in filename:
    count_book(filenames)

18.4 存储数据

很多程序都要求用户输入某种信息,如让用户存储游戏首选项或提供要可视化的数据。不管专注的是什么,程序都把用户提供的信息存储在列表和字典等数据结构中。用户关闭 程序时,你几乎总是要保存他们提供的信息;一种简单的方式是使用模块json 来存储数据。

模块json 让你能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据。你还可以使用json 在Python程序之间分享数据。更重要的是,JSON数据 格式并非Python专用的,这让你能够将以JSON格式存储的数据与使用其他编程语言的人分享。这是一种轻便格式,很有用,也易于学习。

18.4.1 使用json.dump() 和json.load()

我们来编写一个存储一组数字的简短程序,再编写一个将这些数字读取到内存中的程序。第一个程序将使用json.dump() 来存储这组数字,而第二个程序将使 用json.load() 。

函数json.dump() 接受两个实参:要存储的数据以及可用于存储数据的文件对象。下面演示了如何使用json.dump() 来存储数字列表:

import json
number=[1,2,3,4]#创建一个列表
filename='number.json'#创建一个json文件
with open(filename,'w') as file_object:#打开该文件,进行写入
    json.dump(number,file_object)#json.dump()方法将数字列表存储到文件numbers.json中。

下面再编写一个程序,使用json.load() 将这个列表读取到内存中:

import json
filename='number.json'
with open(filename) as file_object:#打开number.json文件
    numbers=json.load(file_object)#json.load()方法读取文件内容
print(numbers)

18.4.2 保存和读取用户生成的数据

对于用户生成的数据,使用json 保存它们大有裨益,因为如果不以某种方式进行存储,等程序停止运行时用户的信息将丢失。下面来看一个这样的例子:用户首次运行程序时 被提示输入自己的名字,这样再次运行程序时就记住他了

import json
username=input('请输入你的用户名:')#让用户输入用户名
filename='number.json'#写入文件的名称
with open(filename,'w') as f_obj:#打开文件
    json.dump(username,f_obj)#进行文件的写入
    print(username+" 欢迎您回来!")

现在再编写一个程序,向其名字被存储的用户发出问候:

import json
filename='number.json'
with open(filename) as f_obj:
    username=json.load(f_obj)
    print('欢迎您! '+username)

18.4.3 重构

你经常会遇到这样的情况:代码能够正确地运行,但可做进一步的改进——将代码划分为一系列完成具体工作的函数。这样的过程被称为重构 。重构让代码更清晰、更易于理 解、更容易扩展。

import json
def greet_user():#定义一个函数
    filename='username.json'
    try:
        with open(filename) as f_ojb:
            username=json.load(f_ojb)
    except FileNotFoundError:
        username= input('请输入你的用户名:')
        with open(filename, 'w') as f_obj:
            json.dump(username, f_obj)
            print('欢迎您回来!' + username)
    else:
        print('欢迎! '+username)
greet_user()

下面来重构greet_user() ,让它不执行这么多任务。为此,我们首先将获取存储的用户名的代码移到另一个函数中:

import json
def get_stored_username():
"""如果存储了用户名,就获取它"""
--snip--
def get_new_username():
"""提示用户输入用户名"""
username = input("What is your name? ")
filename = 'username.json'
with open(filename, 'w') as f_obj:
json.dump(username, f_obj)
return username
def greet_user():
"""问候用户,并指出其名字"""
username = get_stored_username()
if username:
print("Welcome back, " + username + "!")
else:
username = get_new_username()
print("We'll remember you when you come back, " + username + "!")
greet_user()

重构就是为了让每一个函数只执行一次工作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值