Python第九章节——异常,模块与包

发布于:2025-03-25 ⋅ 阅读:(24) ⋅ 点赞:(0)

一.异常

1.异常的概念:

当检测到一个错误时,Python编译器就会报错并且停止执行,这就是"异常"(BUG)

不知道你有没有注意过,在编译器每次报错时都会在最后一行的最前面提示这次出现的是什么样的错误,并且异常的种类是多种多样的

2.异常的捕获

(1).我们进行捕获异常(异常处理)的原因:

这个世上没有任何一个程序是完美的,每一个程序在运行的过程中都有可能出现异常,也就是出现BUG从而导致程序无法完美地运行下去,我们捕获异常的目的就是在力所能及的范围内对可能出现的异常提前准备应对措施

像这样的行为就是我们所说的捕获异常(异常处理)

(2).遇到异常后的情况:

在我们的程序遇到了BUG之后,接下来有两种情况:整个程序都会停止运行或对这个BUG进行提醒,但是程序仍然继续运行

在我们学习地过程中当然是会任由程序崩溃,但是在真实的工作场景中我们肯定还是需要程序继续运行的,在这里就需要使用到捕获异常的手段

捕获异常的作用就在于提前假设某处会出现某种异常,提前对其做好准备,直到真的出现异常时可以有后续的处理手段

(3).捕获异常的基本语法:

try:
# 可能发生错误的代码
except:
# 如果出现异常,那么会执行什么样的代码作为替代

例如,我们以只读(r)模式打开一个文件,而此时这个文件并不存在,那么按理来说就会报错,在检测到这样的文件不存在时我们就以只写(w)模式打开

try: 
# 若能以只读方式打开就是最好,表示没有出现异常
    f = open("test.txt", "r")
except:
# 如果没能找到该文件,出现了异常,那么作为替代就以只写模式获取这个文件对象(创建这么一个文件对象)
    f = open("test.txt", "w")

(4).捕获指定的异常:

在前文也提到了有着多种多样的异常类型,那么如果我们要做到只对指定的某种异常进行处理,那么要怎么做呢?

try:
# 可能会出现异常的代码
except 指定捕获的异常名 as e(取一个别名,不管叫什么都行):
    print("出现异常")

注意:如果出现的不是我们所指定的异常,那么还是会照样报错

(5).捕获多个异常:

当捕获多个异常时只要把要捕获的多个异常的异常类型的名字以元组的形式书写,放在except之后即可

try:
# 可能会出现异常的代码
except (指定捕获的异常名1,指定捕获的异常名2) as e:
    print("出现异常")

(5).在捕获异常时使用else:

这时else表示的是如果没有出现异常,那么要执行的代码是什么

try:
    可能要出现异常的代码
except Exception as e:
    出现异常后要运行的代码
else:
    没有出现异常时要运行的代码

(6).在捕获异常时使用finally:

这时finally表示无论是否代码出现异常,最终都会执行的代码

try:
    可能要出现异常的代码
except Exception as e:
    出现异常后要运行的代码
finally:
    一定会执行的代码

3.异常的传递:

以函数举例,我们写了两个函数,其中第一个函数是最基础的,被第二个函数调用,而在主函数中则是直接调用了第二个函数,这时在第一个函数中出现了异常,异常最终则会被传递到主函数中

def function1():
    函数一的函数体
    # 此时函数体中出现了异常

def function2():
    # 此时在函数二中调用了出现异常的函数一
    function1()

def main():
    try:
        # 在主函数中调用了函数二,但是我们知道可能会出现异常,于是做出了异常捕获措施
        function2()
    except Exception as e:
        出现了异常之后执行的代码

以上方这个例子就可以让大家直观地理解到函数中发生的异常是可以传递的

但是我们还有一个注意事项,如果我们在这时准备了捕获异常的代码,但是在所有我们用到的地方都没有出现异常时,程序也会报错(高版本的编译器现在已经不会再报错了)

def function1():
    print("yeah")

def function2():
    function1()
    print("all right")
# 在function1和function2当中都没有出现异常
def main():
    try:
        # 调用没有异常的function2
        function2()
    except Exception as e:
        print("出现异常")

二.模块

模块的概念:

模块(module)是一个Python文件(以.py结尾), 不知道你们有没有注意过我们使用PyCharm时创建python文件时所创建的都是这种类型的文件,在模块中我们能定义函数,类和变量,在模块里也能包含可执行的代码

换句话说,模块就是一个Python文件,里面有类,函数,变量等等,我们可以导入模块,使用其中定义好的这些内容

1.模块的导入:

# 导入模块的常见使用形式:
import 模块名
form 模块名 import 类,变量,方法等
from 模块名 import *
import 模块名 as 别名
from 模块名 import 功能名 as 别名

2.导入模块并使用的简单案例:

import math

# 调用了math包中开根号的函数
print(math.sqrt(9))

注意:直接使用import方式导入模块和from开头导入模块,在后方的功能使用方面有些许的区别

# from方式
from math import *

# 不再需要使用math.的方式进行调用,直接使用即可
print(sqrt(9))

3.自定义模块

(1).简单的自定义模块案例:

自定义MyModule模块:
# 自定义了一个名字为MyModule的.py文件
def simple_add(x, y):
    return x + y
在其它的Python文件中调用:
import MyModule

print(MyModule.simple_add(10, 20))
注意:

1.在导入模块时from和as别名可以省略

2.通过"."来确定层级关系

3.模块的导入一般写在代码文件的开头位置

4.每个Python文件都可以作为一个模块,模块的名字就是文件的名字,也就是说自定义模块名必须要符合标识符命名的规则

(2).在实际开发时可能会遇到的问题:

在实际开发中,当一个开发人员编写完一个模块之后,为了检测模块是否能够达到预期,开发人员会在py文件中添加一些测试信息,但是如果不对这个测试信息添加限制,在导入模块时也会一起执行测试内容

# 自定义了一个名字为MyModule的.py文件
def simple_add(x, y):
    return x + y

# 例如我在这里调用以下函数看看它的效果如何,然而在别的python文件带哦用本模块时也会一起调用我这下方的测试代码
print(simple_add(1, 2))

在这时,我们可以使用这样一个方法将测试代码限制在仅我们自己测试时使用:

# 自定义了一个名字为MyModule的.py文件
def simple_add(x, y):
    return x + y

# 在我们执行本文件时,传入__name__中的参数就是__main__,也就是说,只有我们执行这个python文件时才会执行测试代码
if __name__ == '__main__':
    print(simple_add(1, 2))

(3).__all__变量的作用:

在我们import *的时候表示的是调用本模块中的所有内容,但是实际上可以理解为调用的是__all__变量中包括的内容(__all__是一个列表)

比如我在自定义模块中这样写:

__all__ = ["simple_add"]

def simple_add(x, y):
    return x + y

def simple_mul(x, y):
    return x * y

# 在我们执行本文件时,传入__name__中的参数就是__main__,也就是说,只有我们执行这个python文件时才会执行测试代码
if __name__ == '__main__':
    print(simple_add(1, 2))
from MyModule import *

# 加入__all__变量的simple_add可以使用,但是simple_mul没有加入,也就不可以使用
print(simple_add(10, 20))
print(simple_mul(10, 20))

注意:在不同模块中可能会有同名的功能,如果两个模块都被导入,并且使用了这个同名的功能,那么后导入的模块中的功能会覆盖先导入的模块中的该功能

三.Python包

概念:

从物理上来看,包就是一个文件夹,在该文件夹下包含了一个__init__.py文件,该文件夹可用于包含多个模块文件

从逻辑上来看,包的本质依然是模块

包的作用:

当我们的模块文件越来越多时,包可以帮助我们分类管理这些模块,包的作用就是包含多个模块,但包的本质仍然是模块

1.自定义包:

在Pycharm中我们能够通过New功能快速的创建一个包,在这个过程中我们需要注意的是:在我们新建包后,在包的内部会自动创建__init__.py文件,这个文件的作用是控制包的导入行为

你们是否还记得在之前我们学习过有关__all__这个变量的相关知识,在我们自己定义包时,就要注意必须要在__init__.py文件中添加__all__变量用以控制允许导入的模块列表(这样在我们以import *的形式导入包之后才可以获取到模块中的内容)

2.第三方包

伴随着Python的发展,大量的第三方包也随之出现了,它们可以极大地帮助我们提高开发效率,但是由于这是第三方提供的,所以Python中并没有内置这些包,我们需要安装这些包之后才可以导入使用

安装方法:

在我们安装了Python之后他就自带了一个pip程序,我们只需要使用pip install 加包名的形式即可通过网络快速安装第三方包

pip install 包名

注意我们是在命令提示符中输入这个命令,而不是在编译软件中

在Pycharm中还可以通过这里添加我们所需要的包