<style></style>
Python学习day09 - Python进阶(3)异常处理1. 什么是异常2. 语法错误3. 逻辑错误4. 万能捕捉异常的方式Python深浅拷贝1. 拷贝(赋值)2. 浅拷贝3. 深拷贝基本的文件操作1. 找到文件路径2. 双击打开3. 看文件4. 写文件5. 关闭文件实战之猜年龄游戏
Python学习day09 - Python进阶(3)
异常处理
1. 什么是异常
异常其实就是我们平时写程序运行程序时的报错,在Python中,异常一般分为两类,即语法错误和逻辑错误
2. 语法错误
语法错误过不了python解释器的语法检测,所以在程序执行之前必须改正,否则程序无法正常执行。
常见如下例:
xxxxxxxxxx4 1
if#SyntaxError: invalid syntax2
3
0 = 1#SyntaxError: can't assign to literal4
语法错误的错误类型基本都是SyntaxError
,后面是较详细的描述。
3. 逻辑错误
逻辑错误不同于语法错误的是,其错误类型比较多样。比如:
xxxxxxxxxx26 1
# TypeError:int类型不可迭代2
for i in 3:3
pass4
5
# ValueError6
num=input(">>: ") #输入hello7
int(num)8
9
# NameError10
aaa11
12
# IndexError13
l=['egon','aa']14
l[3]15
16
# KeyError17
dic={'name':'egon'}18
dic['age']19
20
# AttributeError21
class Foo:pass22
Foo.x23
24
# ZeroDivisionError:无法完成计算25
res1=1/026
res2=1+'str'
4. 万能捕捉异常的方式
当然我们捕捉异常是为了发现,并处理异常,所以这里介绍一种万能的捕获异常的方法:
xxxxxxxxxx5 1
s1 = 'hello'2
try:3
int(s1)4
except Exception as e:5
print(e)
Exception
可以替代所有的异常类型用来赋值输出,非常方便。而实际上现在的解释器本身的报错,定位错误的功能都挺强大的,所以用这个功能比较有限。
Python深浅拷贝
一般Python的拷贝分为以下三种,我们分别介绍,用copy之前记得加上头文件import copy
.
1. 拷贝(赋值)
赋值的常见方式如下:
xxxxxxxxxx7 1
lt = [1, 2, 3]2
lt2 = lt3
print(lt)4
print(lt2)5
lt.append(4)6
print(lt)7
print(lt2)
[1,2,3]
[1,2,3]
[1,2,3,4]
[1,2,3,4]
xxxxxxxxxx1 1
上述打印结果可以看到,lt的值变化,lt2的值也会跟着变化,这就是最一般的赋值
2. 浅拷贝
xxxxxxxxxx6 1
# lt2没有变化的情况2
lt = [1, 2, 3]3
lt2 = copy.copy(lt)4
lt.append(4)5
print(lt) # [1, 2, 3, 4]6
print(lt2) # [1, 2, 3]
以上就是lt2没有跟随lt变化而变化,因为添加修改的是一个字符串,不是可变类型。
xxxxxxxxxx6 1
# lt2变化的情况2
lt = [1, 2, 3,[4,5,6]]3
lt2 = copy.copy(lt)4
lt[3].append(7)5
print(lt) # [1, 2, 3, [4,5,6,7]]6
print(lt2) # [1, 2, 3,[4,5,6]]
该例就是lt2跟随lt变化的情况,因为往里面添加的是修改一个列表,是可变的类型。
3. 深拷贝
深拷贝是最稳定的拷贝,也是对原值保留最好的,永远不会随原值改变。
xxxxxxxxxx15 1
t = [1000, 2000, 3000, [4000, 5000, 6000]]2
print('id(lt)',id(lt))3
print('id(lt[0])', id(lt[0]))4
print('id(lt[1])', id(lt[1]))5
print('id(lt[2])', id(lt[2]))6
print('id(lt[3])', id(lt[3]))7
print('*' * 50)8
lt2 = copy.deepcopy(lt)9
print('id(lt2)',id(lt2))10
print('id(lt2[0])', id(lt2[0]))11
print('id(lt2[1])', id(lt2[1]))12
print('id(lt2[2])', id(lt2[2]))13
print('id(lt2[3])', id(lt2[3]))14
print('*' * 50)15
由以上打印结果可以看出,不管lt怎么改变,lt2都不会随之改变。
- 总结如下:
xxxxxxxxxx8 1
# 牢记: 拷贝/浅拷贝/深拷贝 只针对可变数据类型2
3
# 拷贝: 当lt2为lt的拷贝对象时,lt内的可变类型变化,lt2变化;lt内的不可变类型变化,lt2变化。4
5
#浅拷贝:当lt2为lt的浅拷贝对象时,lt内的可变类型变化,lt2变化;lt内的不可变类型变化,lt2不变化6
7
# 深拷贝: 当lt2为lt的深拷贝对象时,lt内的可变类型变化,lt2不变化;lt内的不可变类型变化,lt2不变8
基本的文件操作
什么是文件呢,之前的博客中有介绍,文件其实就是操作系统提供给用户的一个虚拟单位,是用来存储数据的。那么用Python来对文件操作有以下几个常用的操作。
1. 找到文件路径
xxxxxxxxxx6 1
path = r'D:\Python学习\.idea\Python学习.iml'2
3
# python里就是这样打开文件路径的,以上这种也叫做绝对路径。相对路径可以如下表示4
path = r'Python学习.iml'5
6
#相对路径即你所执行的这个py文件的当前文件夹,会默认在这里搜索
2. 双击打开
xxxxxxxxxx3 1
f = open(path,'w',encoding = 'utf8')2
print(f)3
# r-->只读,w-->只写,清空当前文件后写入,后面的encoding为所打开文件的编码格式
3. 看文件
xxxxxxxxxx2 1
data = f.read()2
print(data)
4. 写文件
xxxxxxxxxx1 1
f.write('fsfda')
5. 关闭文件
xxxxxxxxxx4 1
del f2
f.close()3
4
#需要注意的是,del f只是删除了解释器对文件的引用,并没有真正关闭文件,只有f.close才是真正的关闭文件
实战之猜年龄游戏
这是最近学习遇到的第一个稍有规模的代码,实现方式有很多种,以下两种仅供参考:
题目需求如下:
- 奖励物品存放在文件price.txt
- 给定年龄(随机18-60),用户可以猜三次年龄
- 年龄猜对,让用户选择两次奖励
- 用户选择两次奖励后可以退出
-
常规猜年龄
xxxxxxxxxx
67 1import random
2
3age = random.randint(18, 60) # 随机一个数字,18-60岁
4count = 0 # 计数
5
6f = open('price.txt', 'r', encoding='utf8') # price.txt右下角为什么编码,则encoding为什么编码
7price_dict = f.read()
8price_dict = eval(price_dict) # type:dict # 获取奖品字典
9f.close()
10
11price_self = dict()
12
13while count < 3:
14count += 1
15
16inp_age = input('请输入你想要猜的年龄:')
17
18# 判断是否为纯数字
19if not inp_age.isdigit():
20print('搞事就骂你傻逼')
21continue
22
23inp_age = int(inp_age)
24
25# 筛选年龄范围
26if inp_age > 60 or inp_age < 18:
27print('好好题目,18-60岁,非诚勿扰')
28continue
29
30# 核心逻辑
31if age == inp_age:
32print('猜中了,请选择你的奖品')
33
34# 打印商品
35for k, v in price_dict.items():
36print(f'奖品编号:{k} {v}')
37
38# 获取奖品的两次循环
39for i in range(2):
40price_choice = input('请输入你需要的奖品编号:')
41
42if not price_choice.isdigit():
43print("恭喜你已经获得一次奖品,奖品为空!并且请输入正确的奖品编号!")
44continue
45
46price_choice = int(price_choice)
47
48if price_choice not in price_dict:
49print('你想多了吧!')
50else:
51price_get = price_dict[price_choice]
52print(f'恭喜中奖:{price_get}')
53
54if price_self.get(price_get):
55price_self[price_get] += 1
56else:
57price_self[price_get] = 1
58
59print(f'恭喜你获得以下奖品:{price_self}')
60break
61
62elif age > inp_age:
63print('猜小了')
64elif age < inp_age:
65print('猜大了')
66
67continue
-
抽奖式猜年龄
xxxxxxxxxx
1 74 1import random
2
3age = random.randint(18, 19) # 随机一个数字,18-60岁
4count = 0 # 计数
5
6f = open('price.txt', 'r', encoding='utf8') # price.txt右下角为什么编码,则encoding为什么编码
7price_dict = f.read()
8price_dict = eval(price_dict) # type:dict # 获取奖品字典
9f.close()
10
11price_self = dict()
12
13while count < 3:
14count += 1
15
16inp_age = input('请输入你想要猜的年龄:')
17
18# 判断是否为纯数字
19if not inp_age.isdigit():
20print('搞事就骂你傻逼')
21continue
22
23inp_age = int(inp_age)
24
25# 筛选年龄范围
26if inp_age > 60 or inp_age < 18:
27print('好好题目,18-60岁,非诚勿扰')
28continue
29
30# 核心逻辑
31if age == inp_age:
32print('猜中了,请选择你的奖品')
33
34# 打印商品
35for k, v in price_dict.items():
36print(f'奖品编号:{k} {v}')
37
38# 获取奖品的两次循环
39for i in range(2):
40price_y = input(f'请按"Y or y"转动转盘{chr(9803)}:').lower()
41
42if price_y != 'y':
43print("恭喜你已经获得一次奖品,奖品为空!并且请输入'Y or y'!")
44continue
45
46#
47price_choice = random.randint(0, 10000)
48
49if price_choice > 0 and price_choice < 9900:
50price_choice = 6
51print('恭喜你, 下次一定有好东西!!', end=' ')
52else:
53price_choice = price_choice % 7
54
55if price_choice not in price_dict:
56print('你想多了吧!')
57else:
58price_get = price_dict[price_choice]
59print(f'恭喜中奖:{price_get}')
60
61if price_self.get(price_get):
62price_self[price_get] += 1
63else:
64price_self[price_get] = 1
65
66print(f'恭喜你获得以下奖品:{price_self}')
67break
68
69elif age > inp_age:
70print('猜小了')
71elif age < inp_age:
72print('猜大了')
73
74continue
以上内容均借鉴于恩师nick的博客,希望大家都去借鉴,关注,点赞~
https://www.cnblogs.com/nickchen121/p/10718112.html