探索Python异常世界:玩转异常、模块与包

一 异常概念

  • bug单词的诞生
    1945年9月9日,下午三点,马克二型计算机无法正常工作了,技术人员试了很多办法,最后定位到第70号继电器出错。负责人哈珀观察这个出错的继电器,发现一只飞蛾躺在中间,已经被继电器打死。她小心地用摄子将蛾子夹出来,用透明胶布帖到“事件记录本”中,并注明“第一个发现虫子的实例。”自此之后,引发软件失效的缺陷,便被称为Bug。
  • bug就是指异常的意思,因为历史因为小虫子导致计算机失灵的案例,所以延续至今,bug就代表软件出现错误。

在这里插入图片描述

  • 在Python中,异常是指在程序运行过程中出现的错误或异常情况,它们可以打破正常的程序流程。
  • Python提供了异常处理机制,使得程序在遇到异常时能够优雅地处理错误,避免程序崩溃。

二 异常的捕获方法

2.1 捕获异常的原因

  • 世界上没有完美的程序,任何程序在运行的过程中,都有可能出现:异常,也就是出现bug导致程序无法完美运行下去。

  • 我们要做的,不是力求程序完美运行,而是在力所能及的范围内,对可能出现的bug,进行提前准备、提前处理。这种行为称之为:异常处理(捕获异常)

  • 捕获异常的作用在于:提前假设某处会出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段。

2.2 捕获常规异常

基本语法:

try:
    可能发生错误的代码
except:
    如果出现异常执行的代码
  • 演示:尝试以r模式打开文件,如果文件不存在,则以w方式打开。
    try:
        f = open('linux.txt', 'r')
    except:
        f = open('linux.txt', 'w')
    

2.3 捕获指定异常

try:
    print(name)
except NameError as e:
    print('name变量名称未定义错误')

如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常
一般try下方只放一行尝试执行的代码

  • 常见的Python异常以及如何处理方法
  1. SyntaxError(语法错误):这种异常是在代码中有语法错误时引发的,例如拼写错误、缺少冒号等。

    if x > 10  # 缺少冒号
    
  2. IndentationError(缩进错误):这种异常是由于代码的缩进不正确而引发的,Python通过缩进来表示代码块。

    def my_function():
    print("Hello, World!")  # 缩进不正确
    
  3. NameError(名称错误):当尝试使用一个未定义的变量或函数时,会引发这种异常。

    print(undefined_variable)  # 未定义的变量
    
  4. TypeError(类型错误):当操作应用于错误类型的对象时,会引发这种异常。

    x = "5"
    y = 10
    result = x + y  # 不能将字符串和整数相加
    
  5. ValueError(值错误):当函数接收到一个正确类型但是无效的值时,会引发这种异常。

    int("abc")  # 无效的整数转换
    
  6. IndexError(索引错误):当使用无效的索引访问序列(如列表或字符串)中的元素时,会引发这种异常。

    my_list = [1, 2, 3]
    print(my_list[5])  # 无效的索引
    
  7. FileNotFoundError(文件未找到错误):当尝试打开不存在的文件时,会引发这种异常。

    with open("nonexistent_file.txt", "r") as f:
        content = f.read()
    
  • 为了处理异常,可以使用tryexcept语句块。try块用于包含可能引发异常的代码,而except块用于定义在异常发生时要执行的代码。

    try:
        # 可能引发异常的代码
        result = x / y
    except ZeroDivisionError:
        print("除数不能为零")
    except TypeError as e:
        print(f"类型错误:{e}")
    except Exception as e:
        print(f"发生了其他异常:{e}")
    else:
        print("没有发生异常时执行的代码")
    finally:
        print("无论是否发生异常都会执行的代码")
    
  • try块中的代码将被执行,如果引发了特定类型的异常,将会跳转到相应的except块。如果没有发生异常,将会执行else块中的代码。无论是否发生异常,finally块中的代码都会执行。

2.4 捕获多个异常

  • 当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。
try:
    print(1/0)
except (NameError, ZeroDivisionError):
    print('ZeroDivision错误...')

  • 也可以使用多个except语句来捕获不同类型的异常
try:
    x = int(input("请输入一个整数: "))
    result = 10 / x
except ZeroDivisionError:
    print("除数不能为零")
except ValueError:
    print("请输入有效的整数")
except Exception as e:
    print(f"发生了其他异常:{e}")
else:
    print(f"结果是: {result}")
finally:
    print("程序执行结束")

2.5 捕获异常并输入异常信息

try:
    print(num)
except (NameError, ZeroDivisionError) as e:
    print(e)

2.6 捕获所有异常

try:
    print(name)
except Exception as e:
    print(e)

2.7 异常else

  • else表示的是如果没有异常要执行的代码。
try:
    print(1)
except Exception as e:
    print(e)
else:
    print('我是else,是没有异常的时候执行的代码')

2.8 异常finally

  • finally表示的是无论是否异常都要执行的代码,例如关闭文件。
try:
    f = open('test.txt', 'r')
except Exception as e:
    f = open('test.txt', 'w')
else:
    print('没有异常,真开心')
finally:
    f.close()

三 异常的传递

  • 异常是具有传递性的
  • 异常可以通过函数调用层级进行传递。当在一个函数内部发生异常,如果没有在函数内部处理该异常,它会被传递到调用该函数的地方。这个过程会一直持续,直到异常被处理或者到达程序的顶层,如果在程序的顶层还没有处理异常,那么程序会终止并显示异常信息。

演示

  • 当函数func01中发生异常, 并且没有捕获处理这个异常的时候, 异常会传递到函数func02, 当func02也没有捕获处理这个异常的时候main函数会捕获这个异常, 这就是异常的传递性.
    在这里插入图片描述
  • 利用异常具有传递性的特点, 当我们想要保证程序不会因为异常崩溃的时候, 就可以在main函数中设置异常捕获, 由于无论在整个程序哪里发生异常, 最终都会传递到main函数中, 这样就可以确保所有的异常都会被捕获

三.四 自定义异常

  • 自定义异常类通常是从内置的 Exception 类(或其子类)派生而来
  • 抛出⾃定义异常的语法为 raise 异常类对象
  • 举例:数值不能为复数
    # 自定义的异常类,它从内置的 Exception 类派生
    class CustomError(Exception):
        """自定义异常类"""
    	
        def __init__(self, message="发生了自定义异常"):
            self.message = message
            super().__init__(self.message)
    
    # 引发自定义异常
    def example_function(value):
        if value < 0:
            raise CustomError("值不能为负数")
    
    # 在代码的其他地方捕获自定义异常
    try:
        # 一些可能会引发自定义异常的代码
        raise CustomError("这是一个自定义异常")
    except CustomError as ce:
        print(f"捕获到自定义异常: {ce}")
    

四 python模块

  • 在Python中,模块是一种组织和封装代码的方式。它允许将相关的功能、变量和类组织在一起,以便更好地管理和重用代码。

  • Python中的每个文件都可以被看作是一个模块,文件名就是模块名,不过不包含扩展名。

  • 模块可以包含函数、变量、类和甚至可执行的代码。使用import语句来导入其他模块,以便在代码中使用模块中定义的功能。

  1. 创建模块:要创建一个模块,只需创建一个以.py为后缀的Python文件,并在文件中编写代码。例如,创建一个名为my_module.py的文件,其中包含一些函数和变量。

  2. 导入模块:使用import语句可以在你的代码中导入模块。你可以导入整个模块,也可以只导入其中的特定函数、变量或类。

    import my_module
    from my_module import my_function
    
  3. 使用模块成员:一旦导入了模块,你就可以使用其中定义的函数、变量和类。

    import my_module
    
    result = my_module.my_function(10)
    
  4. 模块的别名:你可以为导入的模块创建别名,以减少输入长度或解决命名冲突。

    import my_module as mm
    result = mm.my_function(10)
    
  5. 标准库模块:Python附带了许多标准库模块,它们提供了各种各样的功能,例如处理文件、网络通信、日期时间等。你可以在Python官方文档中找到这些模块的详细信息。

  6. 第三方模块:除了标准库外,还有许多第三方模块可以通过包管理工具如pip来安装和使用。这些模块可以用于各种任务,从数据分析到Web开发等。

  7. 模块的组织:在大型项目中,模块的良好组织和命名是很重要的。通常,你可以将相关的功能放在同一个模块中,并使用目录结构来组织不同的模块。

  8. 模块文档字符串:每个模块都可以有一个文档字符串(docstring),用于描述模块的功能和使用方法。这对于理解模块的作用非常有帮助。

4.1 模块的导入方式

  1. 完整导入:使用import语句导入整个模块,并使用模块名来访问其中的成员。

    import module_name
    
    result = module_name.function_name(argument)
    
  2. 选择性导入:使用from ... import ...语句只导入模块中的特定成员,而不是整个模块。这样可以减少输入的长度,但需要注意避免命名冲突。

    from module_name import function_name
    
    result = function_name(argument)
    
  3. 导入所有:使用from ... import *语句导入模块中的所有成员。这种方式容易引起命名冲突和可读性问题,因此不推荐使用

    from module_name import *
    
    result = function_name(argument)
    
  4. 模块的别名:为导入的模块创建别名,以减少输入长度或解决命名冲突。

    import module_name as mn
    
    result = mn.function_name(argument)
    
  5. 导入多个成员:使用逗号分隔可以同时导入多个成员。

    from module_name import function1, function2, variable
    
  6. 导入整个模块并取部分成员:同时导入整个模块,但只使用其中的一些特定成员。

    from module_name import function1, function2 as f2
    

4.2 自定义模块

创建自定义模块是将一组相关的函数、类和变量组织在一个文件中,以便在项目中重复使用。下面是创建和使用自定义模块的基本步骤:

  1. 创建模块文件:创建一个以.py为后缀的文件,该文件将成为自定义模块。在文件中定义函数、类和变量

    • 创建一个名为my_module.py的文件,其中包含以下内容:
    def greet(name):
        return f"Hello, {name}!"
    
    def calculate_square(x):
        return x ** 2
    
    PI = 3.14159
    
  2. 导入自定义模块:在其他Python文件中,可以使用import语句导入自定义模块

    import my_module
    
    print(my_module.greet("Alice"))
    print(my_module.calculate_square(5))
    print(my_module.PI)
    
  3. 使用模块中的内容:一旦你导入了自定义模块,就可以使用模块中定义的函数、类和变量

  4. 导入特定成员:如果只想导入模块中的某些特定成员,可以使用from ... import ...语句

    from my_module import greet, PI
    
    print(greet("Bob"))
    print(PI)
    
  5. 使用模块别名:如果模块名过长或可能引起命名冲突,可以为导入的模块创建别名。

    import my_module as mm
    
    print(mm.greet("Charlie"))
    

4.3 测试模块

  • 在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息,例如,在my_module1.py文件中添加测试代码test(1,1)

    def test(a, b):
        print(a + b)
    
    test(1, 1)
    
  • 问题
    此时,无论是当前文件,还是其他已经导入了该模块的文件,在运行的时候都会自动执行test函数的调用

  • 解决方案

    def test(a, b):
        print(a + b)
    
    # 只在当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行test函数调用
    if __name__ == '__main__':
        test (1, 1)
    

4.4 注意事项

在这里插入图片描述

  • 当导入多个模块的时候,且模块内有同名功能. 当调用这个同名功能的时候,调用到的是后面导入的模块的功能

4.5 __all__

  • 如果一个模块文件中有__all__变量,当使用from xxx import *导入时,只能导入这个列表中的元素
    在这里插入图片描述

五 python包

5.1 python包认识

  • 从物理上看,包就是一个文件夹,在该文件夹下包含了一个 init.py 文件,该文件夹可用于包含多个模块文件
  • 从逻辑上看,包的本质依然是模块
    在这里插入图片描述
  • 包的作用: 当模块文件越来越多时,包可以帮助我们管理这些模块, 包的作用就是包含多个模块,但包的本质依然是模块

5.2 快速上手

步骤如下:
① 新建包my_package
② 新建包内模块:my_module1my_module2
③ 模块内代码如下
在这里插入图片描述

  • my_module1.py
def info_print1():
    print("我是模块1的功能函数代码")

  • my_module2.py
def info_print2():
    print("我是模块2的功能函数代码")
  • Pycharm中的基本步骤:
    • 注意:新建包后,包内部会自动创建__init__.py文件,这个文件控制着包的导入行为
      在这里插入图片描述

5.3 导入包方式简述

  1. 方式一:
import 包名.模块名

包名.模块名.目标

from my_package import my_module1
from my_package import my_module2

my_module1.info_print1()
my_module2.info_print2()
  1. 方式二
    • 必须在__init__.py文件中添加__all__ = [],控制允许导入的模块列表
from 包名 import *
  • 包下__init__.py
__all__ = ['my_module1']
# 通过__all__变量,控制import *
from my_package import *
my_module1.info_print1()
my_module2.info_print2()
  • 注意:__all__针对的是 from ... import * 这种方式对 import xxx 这种方式无效

5.4 导入包方式补充

在Python中,包(Package)是一种将相关的模块组织在一起的方式,以便更好地管理和组织代码。一个包是一个包含了一个特殊的__init__.py文件的目录,该目录下可以包含多个模块文件以及子包。

下面是一些导入包的方式:

  1. 导入整个包:使用import语句导入整个包。导入包后,你可以使用包中的模块和子包。

    import my_package
    
    result = my_package.module_name.function_name(argument)
    
  2. 导入包中的模块:使用import语句导入包中的特定模块。当导入了一个包中的模块,需要使用包名.模块名的方式访问模块。

    import my_package.module_name
    
    result = my_package.module_name.function_name(argument)
    
  3. 从包中导入模块:使用from ... import ...语句从包中导入特定模块,这样可以减少输入的长度。

    from my_package import module_name
    
    result = module_name.function_name(argument)
    
  4. 从包中导入子包:从包中导入子包,然后继续在子包中导入模块或子包。

    from my_package import sub_package
    
    result = sub_package.module_name.function_name(argument)
    
  5. 使用包别名:为导入的包创建别名,以减少输入长度。

    import my_package as mp
    
    result = mp.module_name.function_name(argument)
    
  6. 从子包导入模块:从子包中导入模块,类似于从顶级包导入。

    from my_package.sub_package import module_name
    
    result = module_name.function_name(argument)
    

六 第三方包

6.1 第三方包概述

  • 在Python程序的生态中,有许多非常多的第三方包(非Python官方),可以极大的帮助我们提高开发效率,如:
    • 科学计算中常用的:numpy包
    • 数据分析中常用的:pandas包
    • 大数据计算中常用的:pyspark、apache-flink包
    • 图形可视化常用的:matplotlib、pyecharts
    • 人工智能常用的:tensorflow
  • 这些第三方的包,极大的丰富了Python的生态,提高了开发效率。但是由于是第三方,所以Python没有内置,所以需要安装才可以导入使用。

6.2 第三方包管理命令

  • 在Python中,安装第三方包可以通过使用包管理工具pip来完成。
  • pip是Python的官方包管理工具,可以方便地下载、安装和管理各种第三方库和模块。以下是安装第三方包的步骤:
  1. 检查pip安装情况:首先,确保你的Python环境已经安装了pip。你可以在终端中运行以下命令来检查:

    pip --version
    
  2. 安装第三方包:使用以下命令来安装第三方包。将package_name替换为你要安装的包的名称。

    pip install package_name
    

    例如,要安装名为requests的包,可以运行:

    pip install requests
    

    pip将会自动从Python Package Index(PyPI)下载并安装所需的包及其依赖项。

  3. 指定包版本:如果你想安装特定版本的包,可以在安装命令中指定版本号:

    pip install package_name==version
    

    例如:

    pip install requests==2.26.0
    
  4. 升级包:要升级已安装的包到最新版本,可以使用以下命令:

    pip install --upgrade package_name
    
  5. 查看已安装的包:你可以使用以下命令查看当前Python环境中已安装的包:

    pip list
    
  6. 卸载包:如果要卸载一个已安装的包,可以使用以下命令:

    pip uninstall package_name
    

6.3 pip全局配置国内镜像网站

  • 由于访问国外服务器可能较慢,可以配置pip使用国内的镜像源,以提高安装速度。以下是配置pip使用国内镜像网站的步骤:
  1. 备份pip配置文件(可选):在进行配置之前,建议备份一下pip配置文件,以防止出现问题。配置文件一般位于用户主目录下的.pip文件夹中,名为pip.confpip.ini

  2. 创建或编辑pip配置文件:如果没有配置文件,可以在.pip文件夹中创建一个名为pip.conf的文件。如果已经存在,可以直接编辑该文件。

  3. 添加镜像源配置:在配置文件中,添加以下内容来配置pip使用国内镜像网站。这里以使用清华大学的镜像源为例:

    [global]
    index-url = https://pypi.tuna.tsinghua.edu.cn/simple
    
    • 阿里云镜像源
    [global]
    index-url = https://mirrors.aliyun.com/pypi/simple/
    
    • 华为云镜像源
    [global]
    index-url = https://mirrors.huaweicloud.com/repository/pypi/simple
    
    • 豆瓣镜像源
    [global]
    index-url = https://pypi.doubanio.com/simple/
    
    • 中国科学技术大学镜像源
    [global]
    index-url = https://pypi.mirrors.ustc.edu.cn/simple/
    
    • 腾讯云镜像源
    [global]
    index-url = https://mirrors.cloud.tencent.com/pypi/simple
    
  4. 保存配置文件:保存配置文件并关闭。

  5. 测试配置:运行pip命令来测试新的配置是否生效。例如,运行以下命令来安装一个包并观察是否使用了配置的镜像源:

    pip install package_name
    

6.4 pip指定网站下载包

# 这里以清华大学镜像站为例
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称

6.5 PyCharm配置镜像网站

在这里插入图片描述
在这里插入图片描述

镜像源名称镜像源URL
清华大学镜像源https://pypi.tuna.tsinghua.edu.cn/simple
阿里云镜像源https://mirrors.aliyun.com/pypi/simple/
华为云镜像源https://mirrors.huaweicloud.com/repository/pypi/simple
豆瓣镜像源https://pypi.doubanio.com/simple/
中国科学技术大学镜像源https://pypi.mirrors.ustc.edu.cn/simple/
腾讯云镜像源https://mirrors.cloud.tencent.com/pypi/simple

6.6 PyCharm安装第三方包

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值