1、异常处理机制
Python 中,用
try except
语句块捕获并处理异常,其基本语法结构如下所示:
try:
可能产生异常的代码块
except [ (Error1, Error2, ... ) [as e] ]:#(e是别名,可以自己起)
处理异常的代码块1
except [ (Error3, Error4, ... ) [as e] ]:
处理异常的代码块2
except [Exception]:
处理其它异常
该格式中,[] 括起来的部分可以使用,也可以省略。其中各部分的含义如下:
- (Error1, Error2,…) 、(Error3, Error4,…):其中,Error1、Error2、Error3 和 Error4 都是具体的异常类型。显然,一个 except 块可以同时处理多种异常。
- [as e]:作为可选参数,表示给异常类型起一个别名 e,这样做的好处是方便在 except 块中调用异常类型(后续会用到)。
- [Exception]:作为可选参数,可以代指程序可能发生的所有异常情况,其通常用在最后一个 except 块。
从try except的基本语法格式可以看出,try 块有且仅有一个,但 except 代码块可以有多个,且每个 except 块都可以同时处理多种异常。
try except 语句的执行流程如下:
1.首先执行 try 中的代码块,如果执行过程中出现异常,系统会自动生成一个异常类型,并将该异常提交给 Python 解释器,此过程称为
捕获异常
。
2.当 Python 解释器收到异常对象时,会寻找能处理该异常对象的 except 块,如果找到合适的 except 块,则把该异常对象交给该 except 块处理,这个过程被称为
处理异常
。
3.如果 Python 解释器找不到处理异常的 except 块,则
程序运行终止
,Python 解释器也将退出。
事实上,不管程序代码块是否处于 try 块中,甚至包括 except 块中的代码,只要执行该代码块时出现了异常,系统都会自动生成对应类型的异常。但是,如果此段程序没有用 try 包裹,又或者没有为该异常配置处理它的 except 块,则 Python 解释器将无法处理,程序就会停止运行;反之,如果程序发生的异常经 try 捕获并由 except 处理完成,则程序可以继续执行。
示例:
try:
a = int(input("输入被除数:"))
b = int(input("输入除数:"))
c = a / b
print("您输入的两个数相除的结果是:", c )
except (ValueError, ArithmeticError):
print("程序发生了数字格式异常、算术异常之一")
except :
print("未知异常")
print("程序继续运行")
运行结果为:
程序出错了 try里面的内容不会被执行
上面程序中,第 6 行代码使用了(ValueError, ArithmeticError)来指定所捕获的异常类型,这就表明该 except 块可以同时捕获这 2 种类型的异常;第 8 行代码只有 except 关键字,并未指定具体要捕获的异常类型,这种省略异常类的 except 语句也是合法的,它表示可捕获所有类型的异常,一般会作为异常捕获的最后一个 except 块。
除此之外,由于 try 块中引发了异常,并被 except 块成功捕获,因此程序才可以继续执行,才有了“程序继续运行”的输出结果。
获取特定异常的有关信息
通过前面的学习,我们已经可以捕获程序中可能发生的异常,并对其进行处理。但是,由于一个 except 可以同时处理多个异常,那么我们如何知道当前处理的到底是哪种异常呢?
其实,每种异常类型都提供了如下几个属性和方法,通过调用它们,就可以获取当前处理异常类型的相关信息:
- args:返回异常的错误编号和描述字符串;
- str(e):返回异常信息,但不包括异常信息的类型;
- repr(e):返回较全的异常信息,包括异常信息的类型。
try:
1/0
except Exception as e:
# 访问异常的错误编号和详细信息
print(e.args)
print(str(e))
print(repr(e))
运行结果为:
从程序中可以看到,由于 except 可能接收多种异常,因此为了操作方便,可以直接给每一个进入到此 except 块的异常,起一个统一的别名 e。
Python try except finally:资源回收
Python 异常处理机制还提供了一个 finally 语句,通常用来为 try 块中的程序做扫尾清理工作。
在整个异常处理机制中,finally 语句的功能是:
无论 try 块是否发生异常,最终都要进入 finally 语句,并执行其中的代码块
。
示例:
try:
a = int(input("请输入 a 的值:"))
print(20/a)
except:
print("发生异常!")
finally :
print("执行 finally 块中的代码")
运行结果为:
可以看到,当 try 块中代码没有发生异常时,except 块不会执行,finally 块中的代码会被执行。
可以看到,当 try 块中代码发生异常时,except 块得到执行,而finally 块中的代码仍然会被执行。
finally 块的强大还远不止此,即便当 try 块发生异常,且没有合适和 except 处理异常时,finally 块中的代码也会得到执行。例如:
try:
#发生异常
print(20/0)
finally :
print("执行 finally 块中的代码")
运行结果为:
可以看到,当 try 块中代码发生异常,导致程序崩溃时,在崩溃前 Python 解释器也会执行 finally 块中的代码。
2、Python模块和包
2.1 什么是Python模块
模块,可以理解为是
对代码更高级的封装
,即把能够实现某一特定功能的代码编写在同一个 .py 文件中,并将其作为一个独立的模块,这样既可以方便其它程序或脚本导入并使用,同时还能有效避免函数名和变量名发生冲突。
示例
在相同的目录下导入模块
在同一目录下目录下(桌面也可以)创建一个名为 hello.py 文件,其包含的代码如下:
def say ():
print("Hello,World!")
在同一目录下,再创建一个 say.py 文件,其包含的代码如下:
#通过 import 关键字,将 hello.py 模块引入此文件
import hello
hello.say()
运行 say.py 文件,其输出结果为:
Hello,World!
在不相同的目录下导入模块
在目录
D:\Download\python\p1\P1_1
创建一个名为 TXJS.py 文件,其包含的代码如下:
import math #导入 python的内置函数 math库
# 图形计算
#计算圆形周长
def yuanZc(b): #同时返回多个值
zc = 2 * math.pi * b #2Πr
return zc #将周长返回
在目录
D:\Download\python\p1
,创建一个 DRK.py 文件,其包含的代码如下:
# 导入模块
import P1_1.TXJS
print(P1_1.TXJS.yuanZc(6))
运行 DRK.py 文件,其输出结果为:
37.69911184307752
当调用模块中的 say() 函数时,使用的语法格式为“
模块名.函数
”,这是因为,相对于 say.py 文件,hello.py 文件中的代码自成一个命名空间,因此在调用其他模块中的函数时,需要明确指明函数的出处,否则 Python 解释器将会报错。
2.2 Python导入模块
import 模块名 as 别名
import 模块名1 [as 别名1], 模块名2 [as 别名2],…
:使用这种语法格式的 import 语句,会导入指定模块中的所有成员(包括变量、函数、类等)。不仅如此,当需要使用模块中的成员时,需用该模块名(或别名)作为前缀,否则 Python 解释器会报错。
# 导入sys整个模块
import sys
# 使用sys模块名作为前缀来访问模块中的成员
print(sys.argv[0])
上面第 2 行代码使用最简单的方式导入了 sys 模块,因此在程序中使用 sys 模块内的成员时,必须添加
模块名
作为前缀
。
运行上面程序,可以看到如下输出结果(sys 模块下的 argv 变量用于获取运行 Python 程序的命令行参数,其中
argv[0] 用于获取当前 Python 程序的存储路径)
:
D:/Download/python/p1/hello.py
导入整个模块时,也可以为模块指定别名。例如如下程序:
# 导入sys整个模块,并指定别名为s
import sys as s
# 使用s模块别名作为前缀来访问模块中的成员
print(s.argv[0])
第 2 行代码在导入 sys 模块时才指定了别名 s,因此在程序中使用 sys 模块内的成员时,必须添加模块别名 s 作为前缀。运行该程序,可以看到如下输出结果:
D:/Download/python/p1/hello.py
也可以一次导入多个模块,多个模块之间用逗号隔开。例如如下程序:
# 导入sys、os两个模块
import sys,os
# 使用模块名作为前缀来访问模块中的成员
print(sys.argv[0])
# os模块的sep变量代表平台上的路径分隔符
print(os.sep)
上面第 2 行代码一次导入了 sys 和 os 两个模块,因此程序要使用 sys、os 两个模块内的成员,只要分别使用 sys、os 模块名作为前缀即可。在 Windows 平台上运行该程序,可以看到如下输出结果(os 模块的 sep 变量代表平台上的路径分隔符):
D:/Download/python/p1/hello.py
\
在导入多个模块的同时,也可以为模块指定别名,例如如下程序:
# 导入sys、os两个模块,并为sys指定别名s,为os指定别名o
import sys as s,os as o
# 使用模块别名作为前缀来访问模块中的成员
print(s.argv[0])
print(o.sep)
上面第 2 行代码一次导入了sys 和 os 两个模块,并分别为它们指定别名为 s、o,因此程序可以通过 s、o 两个前缀来使用 sys、os 两个模块内的成员。在 Windows 平台上运行该程序,可以看到如下输出结果:
D:/Download/python/p1/hello.py
\
3、随机函数
1. random()函数
描述:random() 方法返回随机生成的一个实数,它在[0,1)范围内。
语法:
import random
random.random();
注意
:random()是不能直接访问的,需要导入 random 模块,然后通过 random 静态对象调用该方法。
实例:
import random
num = random.random()
print(num)
运行结果为:
0.5915081707521336
2. randrange()函数
描述: randrange() 方法返回指定递增基数集合中的一个随机数,基数缺省值为1。返回一个整数
语法:
import random
random.randrange ([start,] stop [,step])
参数:
start – 指定范围内的开始值,包含在范围内
stop – 指定范围内的结束值,不包含在范围内。
step – 指定递增基数
实例:
import random
num0 = random.randrange(5) #随机取0到5的数,不包括5
num1 = random.randrange(5,10) #随机取5到10的数,不包括10
num2 = random.randrange(5,10,3)#从5到10的数,随机取指定递增基数为3的数,如:5,8
num3 = random.randrange(5,10,3)
print(num0)
print(num1)
print(num2)
print(num3)
执行结果为:
1
7
5
8
3.randint()函数
描述:randint()方法将随机生成一个整数,它在[x,y]范围内 ;有点等价于randrange(x,y+1)。
语法:
import random
random.randint(x,y)
参数:
x – 指定范围内的开始值,包含在范围内
y – 指定范围内的结束值,包含在范围内。
实例:
import random
# random.ranint(start,stop),产生一个从start到stop之间的随机整数,包含start和stop
import random as rd
print(rd.randint(1,3)) #随机输出1到3的数字,包括3
执行结果为:
3
4. uniform()函数
描述:uniform() 方法将随机生成下一个实数,它在[x,y]范围内。返回一个浮点数 。
语法:
import random
random.uniform (x,y)
参数:
x – 指定范围内的开始值,包含在范围内。
y – 指定范围内的结束值,包含在范围内。
实例:
>>> print random.uniform(5,10);
9.13282585434
>>> print random.uniform(9,10);
9.95958315062
5. choice()函数
描述:choice() 方法返回一个列表,元组或字符串的随机项。
语法:
import random
random.choice(x)
参数:
x – list,tuple,strings的一种
实例:
import random
num0 = random.choice(('a','be',5,'e'))
num1 = random.choice([10,2,6,5,85,'af'])
num2 = random.choice('i love python')
print(num0, num1, num2)
运行结果为:
5 2 y
6. sample()函数
描述:sample()方法返回随机从列表,元组或字符串其中部分随机项 ;返回类型为元组类型。
语法:
import random
random.sample(x,n)
参数:
x – list,tuple,strings的一种
n – 返回n个随机项
实例:
>>> print random.sample('i love python',3)
[' ', 'e', 'i']
>>> print random.sample([10,20,50,23,'ab'],3)
[50, 'ab', 23]
>>> print random.sample((10,20,50,23,'ab'),3)
[50, 20, 'ab']
7. shuffle()函数
描述:shuffle() 方法将序列的所有元素随机排序。类似于洗牌。
语法 :
import random
random.shuffle(x)
参数:
x – list,tuple的一种;python2.x只支持list类型
实例:
>>> list=['a','b','c','d','e'];
>>> random.shuffle(list);
>>> print list;
['c', 'd', 'a', 'e', 'b']