13_python笔记-异常处理-Python2/3差异

本文详细介绍了Python中的异常处理机制,包括常见的异常类型、异常处理的基本语法(try...except...)、异常的嵌套处理以及如何手动触发异常。此外还讨论了Python 2与Python 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mycpen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值