13_python笔记-异常处理-Python2/3差异
博客cpen_web
回顾1
模块:python文件
包:包含模块的目录
导入
import math
from math import sqrt
from math import *
importlib
模块导入注意事项
重复导入·只会执行一次
不同模块导入相同模块/函数名·使用后导入的
使用别名区别,或者使用别名简化模块名称·import pandas as pa
绝对导入和相对导入
相对导入
使用. 或者… 此方式导入
注意top-level的位置·程序入口执行文件
只能在top-level下一层之后的包中,路径使用相对导入
绝对导入
相对于top-level的位置,使用模块包的绝对路径
下划线
双下划线开头和双线划线结尾的标识符·python中的内建变量或者函数
以下划线开头的变量·from xxx import *·不会被识别到
注意自定义的标识符最好不要以双下划线开头和双下划綫结尾
内建标识符
name
文件自己执行时:main
模块被导入时:模块此时导入包的绝对路径
file
模块在磁盘中的绝对路径,实际位置
import
打包与发布
1、创建模块包 python_test
2、在python_test目录创建__init__.py以及程序块
3、在python_test同级目录下创建setup.py
from setuptools import setup
setup(
name="pythontest01",
url="http://www.sanlelearning.com",
version="0.0.1",
packages = ["python_test"],
author = "wen",
author_email = "343292019@qq.com",
install_requires = ['xlrd>=1.1.0'],
description = "this is test pack"
)
4、运行python3 setup.py check 进行检查
5、运行python3 setup.py sdist 生成 .tar.gz压缩包,在同目录下会生成一个dist目录,压缩包就放在此目录下
6、安装
pip3 install pythontest01-0.0.1.tar.gz
或者
tar xf pythontest01-0.0.1.tar.gz
cd pythontest01
python3 setup.py install
练习
编写一个以自己名字的模块,实现以下功能:
做为 Apple Store App 独立开发者,你要搞限时促销,为你的应用生成激活码(或 者优惠券),使用 Python 如何生成N 个激活码(或者优惠券)?
·前置模块:random、string
·32位由A-Z0-9组成的数字
·N由用户输入(注意判断输入是否合法)
·注意文档注释
·将文件发布并安装到自己的机器
·将激活码放到文件
示例1
from random import sample
from string import ascii_uppercase
from string import digits
N = input("激活码数量:")
if N.isdigit():
for i in range(int(N)):
print(''.join(sample(ascii_uppercase + digits, 32))) # 注:sample随机生成不重复
else:
print("格式不正确")
示例2
import random
def func():
squ = 'abcdefghigklmnopqrstuvwxyz0987654321'
num = input('请输入您需要的激活码个数:')
if num.isdigit():
for i in range(int(num)):
codes = []
for j in range(4):
code = ''.join(random.sample(str.upper(squ), 8))
codes.append(code)
print('-'.join(codes))
else:
print('请输入数字!')
if __name__ == '__main__':
func()
示例3
quyu = string.digits +string.ascii_letters
def get_key(n):
key = ''
for i in range(1,n+1):
key += random.choice(quyu) #获取随机字符或数字
if i % 4 == 0 and i !=n: #每隔4个字符增加'-'
key += '-'
print(key)
return key
def get_all_keys():
tmp=[]
for i in range(m):
one_key = get_key(n)
if one_key not in tmp: #去掉重复key
tmp.append(one_key)
for key in tmp:
with open('3.txt','a+') as f:
f.write(key+'\n') #写入激活码
#f.write('\r\n')
m = int(input('输入要生成的激活码数量,输入0退出:'))
n = int(input('输入激活码长度'))
get_all_keys()
知识点2 错误与异常
什么是错误
·语法错误(大小写拼写错误、括号不匹配等…)=> 不能正常执行
·逻辑错误(程序运行正常,只是最后结果不符合预期)
什么是异常
·程序运行过程中,出现的意料之外的错误
·如:打开的文件不存在、被除数为0、操作的数据类型不对、存储错误,互联网请求错误…
回溯信息
·当程序运行时,发生了未处理的异常,Python就将终止执行程序,并以堆栈回溯(Traceback,也称向后追踪)的形式显示异常发生的上下文。
·回溯信息告诉我们应该去哪里寻找问题的根源,对解决问题非常有帮助。
#注:出现错误异常,程序就立即终止
示例:出现错误异常,程序就立即终止
print("start......")
f = open("test.txt")
print("ending......")
Traceback (most recent call last): # 注:回溯信息Traceback
File "E:/sanchuang/lianxi/13am.py", line 6, in <module>
f = open("test.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'test.txt' # 注:没有这个文件
知识点3 常见异常类
示例1
#常见异常
#nameerror
print(b)
#ZeroDivisionError 除数为0
a = 1/0
#IndentationError: unexpected indent 缩进错误
print("ok")
#SyntaxError: invalid syntax 语法错误
if 1>0::
print("ok")
#IndexError: list index out of range list的下标超出了范围
a=[1,2,3]
print(a[4])
#keyerror KeyError: 'c' 推荐使用get属性获取值
a = {"a":1,"b":2}
print(a["c"], a.get("c",0)) # 推荐使用get属性获取值
#AttributeError: module 'math' has no attribute 'xxx' 没有这个属性
import math
math.xxx()
#valueError ValueError: invalid literal for int() with base 10: 'abc'
#传递的参数类型不正确
int("abc")
示例2
>>> import math
>>> dir(math) # 注:查看属性
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh'………………
知识点4 Python异常处理
4.1 异常处理
在代码被解释执行的过程中可能会抛出异常。
那么也就是说,可能会发生,可能不会发生。对于这么不可预测的异常状态如何处理?
1:即使程序出错,也不想让程序终止
2:如果出错了,需要特殊处理
异常处理机制 try…except…
4.2 简单的异常处理的格式
4.3 执行顺序:
·正常执行: try -> 执行代码 -> 结束
·遇到异常: try -> 遇到异常 -> 跳到except -> 结束
示例:try…except… 捕获
try:
print("start try......")
a = 1/0
print("end try.....")
except IndexError as ie: # 注:捕获异常 序列超出范围
print("index error")
except ZeroDivisionError as ze: # 注:除数为0的异常
print("zero error")
print("ending......")
try:
print("start try......")
a = 1/0
print("end try.....")
except IndexError as ie: # 注:捕获异常
print("index error",ie)
except ZeroDivisionError as ze:
print("zero error",ze)
print("ending......")
start try......
zero error division by zero # 注:ze错误信息,除数为0
ending......
4.4 except分支可以有多个
4.5 执行顺序:
·执行匹配到第一个except则退出
·如果父类异常在最前面,会吞噬所有子类异常(建议:先except子类,再except父类)
·如果except捕获的错误与触发的错误不一致,程序会捕获不到 # 注:在后面加except Exception
#注:try…except…捕获
#注:except可以有多个
#注:except捕获的错误与程序除法的触发不一致,程序就会捕获不到
#注:except匹配到第一个就退出
#如果父类异常在最前面,会吞噬所有的子类异常
示例1:except捕获的错误与程序触发的错误不一致,程序就会捕获不到
try:
print("start try......")
a = 1/0
print("end try.....")
except IndexError as ie: # 注:捕获异常
print("index error",ie)
# except ZeroDivisionError as ze:
# print("zero error",ze)
print("ending......")
ZeroDivisionError: division by zero
示例2:如果父类异常在最前面,会吞噬所有的子类异常
建议:先except子类,再except父类
try:
a = 1/0
except Exception as e: # 注:Exception基本上所有异常类的父类
print("exception:",e)
except ZeroDivisionError as ze: # 注:没有捕获到子类异常
print("zero error",ze)
print("ending......")
exception: division by zero
ending......
示例3:建议 先except子类,再except父类
try:
print("start try......")
a = 1/0
print("end try.....")
except IndexError as ie:
print("index error",ie)
except ZeroDivisionError as ze:
print("zero error",ze)
except Exception as e:
print("exception:",e)
print("ending......")
4.6 else子句:没有发生异常时执行
4.7 finally子句:不管异常有没有发生都执行
示例1:else子句
# else结构
# 没有发生任何异常时处理else的语句块
try:
print("start try...")
except Exception as e:
print("exception error")
else:
print("this is else test")
try:
print("start try...")
a = 1/0 # 注:发生异常
except Exception as e:
print("exception error")
else:
print("this is else test") # 注:发生异常,没有处理else的语句块
示例2:finally子句
# finally
# 不管有没有异常,不管异常有没有被捕获都执行
try:
print("start try...")
a = 1/0 # 注:异常未被捕获
a = [1,2,3,4] # 注:异常捕获
print(a[5])
except IndexError as ie:
print("index error")
finally: # 注:不管有没有异常,不管异常有没有被捕获都执行
print("this is finally test")
示例3
try:
a = 1/0
print("start...")
except ZeroDivisionError as ze:
print("zero error")
else:
print("code ok")
finally:
print("finally")
输出为:
zero error
Finally
示例4
try:
# a = 1/0
print("start...")
except ZeroDivisionError as ze:
print("zero error")
else:
print("code ok")
finally:
print("finally")
输出为:
start…
code ok
Finally
练习5
输入学生成绩,成绩范围0-100
·从键盘接收成绩
·确保输入的是一个整数
·确保输入的范围为[0, 100] ( 给出相关提示 ),否则不能往后计算
示例
try:
a = int(input("请输入0-100整数:"))
if a > 100 :
raise IndexError # 注:raise 手动触发 IndexError
if a < 0:
raise RuntimeError # 注:raise 手动触发 RuntimeError
except ValueError as ve: # 注:不是整数,int不能转换 ValueError
print("你输入的不是整数")
except IndexError:
print("你输入的数字大于100")
except RuntimeError:
print("你输入的数字小于0")
知识点6 手动触发异常(raise 异常名)
手动触发异常(raise 异常名)
·raise 异常类(”错误说明信息“)
示例
# raise手动触发异常
# raise异常类(“说明信息”)
# raise没有接异常类,默认抛出RuntimeError异常类
try:
print("raise error")
raise # 注:手动触发异常
print("raise error end...") # 注:默认RuntimeError 运行过程中的异常
except Exception as e:
print("raise error end...")
print(e)
# 注:raise抛出的异常类属于runtimeerror异常类
#可以手动抛出异常类,和添加说明信息
raise IndexError("this is test error")
except Exception as e:
print("exception error")
print(e)
知识点7 异常嵌套
嵌套异常
#注:finally在函数退出之前,都会执行
示例1
# 嵌套异常
def aa():
try:
a = "hello world"
try:
int(a)
except ValueError as e:
print("Value Error") # 注:第1个输出
return "i am value error" # 注:函数执行到return 函数结束,return 返回值,只有打印的时候才会出来
finally: # 注:函数的返回值默认为None
print("i am finally error") # 注:无论有没有return,finally都要执行
print("xxxxxxxxxx")
b = [1,2,3]
print(b[3])
except IndexError as msg:
print("Index Error")
finally:
print("i am index error finally")
b = aa()
print("------------")
print(b) # 注:打印函数的返回值 i am value error
Value Error
i am finally error
i am index error finally
------------
i am value error
示例2
# 嵌套异常
def aa():
try:
a = "hello world"
try:
# int(a)
a = "ac"
except ValueError as e:
print("Value Error")
return "i am value error"
finally:
print("i am finally error") # 注:首先输出
print("xxxxxxxxxx") # 注:第2 输出
b = [1,2,3]
print(b[3])
except IndexError as msg:
print("Index Error") # 注:第3 输出
finally:
print("i am index error finally") # 注:第4输出
b = aa()
print("------------") # 注:第5 输出
print(b) # 注:最后输出 为None
i am finally error
xxxxxxxxxx
Index Error
i am index error finally
------------
None
搭配非常灵活
try:
int("abc")
except:
print("test finally")
try:
int("abc")
finally:
print("test finally")
知识点8 异常处理注意事项
异常处理注意事项
·只执行最先匹配的一个except
·如果父类异常在最前面,会吞噬所有子类异常
·多except注意:
·只会匹配一个except
·要先写子类异常再写父类异常
·如果except捕获的错误与触发的错误不一致,程序会捕获不到
知识点9 几点建议
几点建议
·不建议使用异常来代替常规的检查,如if…else判断
·避免过多依赖于异常处理机制
·在必要的时候,可以手动引发异常(raise)=> 函数或方法
知识点10
在函数中,需要注意在try/except/finally使用return
·在finally中使用return,异常无法回溯
·在函数中的try/except语句使用return后,仍然会执行finally中的内容
·finally => 正常或异常都执行
·return => 直接退出函数,返回值给主程序
知识点11 关于性能
示例
[root@sanchuang-linux try_test]# cat try_test.py
for i in range(10000000): # 注:执行10000000次try
try:
a=1
except: # 注:except:不接参数 默认捕获exception异常(基本所有异常)
pass
[root@sanchuang-linux try_test]# cat try_test2.py
try:
for i in range(10000000):
a=1
except:
pass
#注:命令之前+time 获取命令执行的时间
[root@sanchuang-linux try_test]# time python3 try_test.py
real 0m0.766s
user 0m0.686s
sys 0m0.006s
[root@sanchuang-linux try_test]# time python3 try_test2.py
real 0m0.616s
user 0m0.602s
sys 0m0.005s
#注:第二种好一点,for循环在try里面
知识点12 python2与python3的差异
安装python2
[root@sanchuang-linux try_test]# yum list|grep python2
[root@sanchuang-linux try_test]# yum install python2
主要差异点
1、输入输出
输入
Python2:input默认接收int类型,str类型接收需要使用引号包起来,raw_input得到一个str类型
Python3:input得到str类型(就是python2中的raw_input)
输出print
Python2: # 注:两种都可以
>>> print "ok"
ok
>>> print("ok")
ok
Python3: # 注:只能作为函数输出
>>> print("ok")
ok
输入
Python2:input默认接收int类型,str类型接收需要使用引号包起来,raw_input得到一个str类型
>>> a = input("请输入:")
请输入:1
>>> type(a)
<type 'int'>
>>> b = input("请输入:")
请输入:b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'b' is not defined
>>> b = input("请输入:")
请输入:"b"
>>> type(b)
<type 'str'>
>>> c = raw_input("请输入:")
请输入:1
>>> type(c)
<type 'str'>
Python3:input得到str类型(就是python2中的raw_input)
>>> a = input("请输入:")
请输入:1
>>> type(a)
<class 'str'>
2、数据类型及运算符
数据类型
Python2:整型区分 长整型和整型
Python3:都是整型
Python2
>>> a=99999999999999999999999999999999999999999
>>> type(a)
<type 'long'>
Python3
>>> a=999999999999999999999999999999
>>> type(a)
<class 'int'>
整除
Python2:实际是地板除,要想得到真除,变成浮点数再相除
Python3:就是真除
示例
Python2
>>> 5/3
1
>>> 5.0/3
1.6666666666666667
Python3
>>> 5/3
1.6666666666666667
3、range与xrange
Python2:range(4),结果是一个列表生成[0,1,2,3];xrange返回一个课迭代对象生成器,使用的时候再创建对象
Python3:range就是Python2的xrange # 注:自己本身没有xrange函数
示例
Python2
>>> range(4)
[0, 1, 2, 3] # 注:生成的是列表,一次性加载到内存里面,一开始就生成一个列表,一次性返回
>>> xrange(4) # 注:占的内存比range小
xrange(4)
Python3
>>> range(4) # 注:python3里没有xrange
range(0, 4) # 注:生成器,取的时候才生成这个数
4、异常机制
Python2:可以用 , (逗号)也可以用as
Python3:只能用as # 注:把信息赋给一个标识符的时候
示例
Python2
>>> try:
... print("ok")
... except Exception,e: # 注:python2中 ,e
... print("exception error") # 注:python2中 也可以用as e
...
ok
Python3
>>> try:
... print("ok")
... except Exception as e: # 注:python3中 as e
... print("exception error")
...
ok
5、字符编码
Python2:默认编码为ascii码
Python3:默认编码方式utf-8
Python2中含有中文 要声明编码方式
#-*-coding: utf-8-*- # 注:方法1
encoding=utf-8 # 注:方法2
示例
[root@sanchuang-linux try_test]# cat python2_file.py
#你好
print("ok")
[root@sanchuang-linux try_test]# cat python3_file.py
#你好
print("ok")
[root@sanchuang-linux try_test]# python2 python2_file.py
File "python2_file.py", line 2
SyntaxError: Non-ASCII character '\xe4' in file python2_file.py on line 2, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
[root@sanchuang-linux try_test]# python3 python3_file.py
ok
[root@sanchuang-linux try_test]# vim python2_file.py
[root@sanchuang-linux try_test]# cat python2_file.py
#-*-coding: utf-8-*- # 注:添加以后运行正常
#你好
print("ok")
[root@sanchuang-linux try_test]# python2 python2_file.py
ok
6、布尔类型
Python2:True、False可以定义成标识符,可以改变
Python3:True、False变成了关键字,不能修改
示例
Python2
>>> True=2
>>> False=3
Python3
>>> True=2
File "<stdin>", line 1
SyntaxError: can't assign to keyword
7、模块导入
Python2:默认使用相对导入
Python3:默认是绝对导入
Python2 future
使用__future__模块 向后兼容 # 注:比如python2 想使用python3的语法
示例:Python2中
>>> True=2
>>> False=3
>>> from __future__ import division
>>> 5/4
1.25
本文详细介绍了Python中的异常处理机制,包括常见的异常类型、异常处理的基本语法(try...except...)、异常的嵌套处理以及如何手动触发异常。此外还讨论了Python 2与Python 3之间的差异。

33万+

被折叠的 条评论
为什么被折叠?



