Python异常处理机制详解:从基础到自定义

叶初
叶初
发布时间:2026-10-15| 5人浏览过
原创

本文系统讲解Python中的异常处理机制,涵盖常见内置异常类型、try-except-else-finally完整语法结构、多分支与万能异常Exception的使用,以及通过raise语句抛出异常和创建自定义异常类的方法。同时介绍assert断言在条件检查中的应用,帮助开发者编写更健壮的代码。

一、什么是异常

在Python中,错误会触发相应的异常对象。

二、异常的种类

Python使用不同的异常类型来标识各类错误,每种异常对应一种具体的错误情况。

1、常用异常类

  • AttributeError:尝试访问对象不存在的属性,例如执行foo.x,但对象foo并未定义x属性。
  • IOError:输入/输出操作异常,通常表现为无法打开文件。
  • ImportError:无法导入模块或包,通常由路径错误或模块名称拼写错误引起。
  • IndentationError:语法错误的子类,表示代码缩进不正确。
  • IndexError:序列索引超出边界,例如列表x仅有三个元素,却尝试访问x[5]。
  • KeyError:尝试访问字典中不存在的键。
  • KeyboardInterrupt:用户按下Ctrl+C中断程序执行。
  • NameError:访问未赋值的变量。
  • SyntaxError:Python代码语法非法,导致无法编译(通常因代码书写错误引起)。
  • TypeError:传入的对象类型与函数或操作要求不符。
  • UnboundLocalError:尝试访问尚未设置的局部变量,通常是因为存在同名全局变量导致混淆。
  • ValueError:传入的值类型正确,但数值不符合调用者的期望。

2、异常举例:

# TypeError:int类型不可迭代
for i in 3:
    pass

# ValueError
num=input(">>: ") #输入hello
int(num)

# NameError
aaa

# IndexError
l=['egon','aa']
l[3]

# KeyError
dic={'name':'egon'}
dic['age']

# AttributeError
class Foo:pass
Foo.x

# ZeroDivisionError:无法完成计算
res1=1/0
res2=1+'str'

三、异常处理

1、基本语法try...except

try:
    被检测的代码块
except 异常类型:
    try中一旦检测到异常,就执行这个位置的逻辑

示例代码展示基本的异常捕获流程。

try:
    f = [ 'a', 'a', 'a','a','a', 'a','a',]
    g = (line.strip() for line in f) #元组推导式
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
except StopIteration:
    f.close()

异常类仅能处理指定的异常情况,若发生非指定异常,则无法被当前except块捕获。

s1 = 'hello'
try:
    int(s1)
except IndexError as e:  # 未捕获到异常,程序直接报错
    print(e)

2、多分支异常 except..except与万能异常:Exception

s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
except Exception as e:
    print(e)

3、try/except...else

try/except语句包含一个可选的else子句,该子句必须置于所有except子句之后。

当try子句执行过程中未发生任何异常时,else子句中的代码将被执行。

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

4、异常的最终执行finally

try-finally语句无论是否发生异常,finally块中的代码始终会执行。

定义清理行为:

s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
#except Exception as e:
#    print(e)
else:
    print('try内代码块没有异常则执行我')
finally:
    print('无论异常与否,都会执行该模块,通常是进行清理工作')

#invalid literal for int() with base 10: 'hello'

#无论是否发生异常,该模块代码都会执行,通常用于资源清理工作。

四、抛出异常raise

Python使用raise语句主动抛出一个指定的异常。

raise语法的格式如下:

raise [Exception [, args [, traceback]]]
try:
    raise TypeError('抛出异常,类型错误')
except Exception as e:
    print(e)

raise后跟随的唯一参数指定了要抛出的异常,该参数必须是异常类的实例或异常类本身(即Exception的子类)。

如果仅需确认异常是否被抛出而不打算处理,可使用简单的raise语句将当前异常再次抛出。

try:
        raise NameError('HiThere')
    except NameError:
        print('An exception flew by!')
        raise
   
#An exception flew by!
#Traceback (most recent call last):
#  File "", line 2, in ?
#NameError: HiThere

五、自定义异常

可以通过创建新的异常类来自定义异常。异常类应继承自Exception类,支持直接继承或间接继承,例如:

在此示例中,Exception类的默认__init__()方法被重写。

class EgonException(Exception):
    def __init__(self, msg):
        self.msg = msg

    def __str__(self):
        return self.msg


try:
    raise EgonException('抛出异常,类型错误')
except EgonException as e:
    print(e) 

#抛出异常,类型错误

基础异常类

当创建可能抛出多种异常的模块时,通常的做法是建立基础异常类,并基于该类派生出针对不同错误情况的子类:

大多数异常名称以"Error"结尾,这与标准异常命名规范一致。

class Error(Exception):
    """Base class for exceptions in this module."""
    pass
 
class InputError(Error):
    """Exception raised for errors in the input.
 
    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """
 
    def __init__(self, expression, message):
        self.expression = expression
        self.message = message
 
class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.
 
    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """
 
    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message

六、断言assert

assert(断言)用于验证表达式,当表达式条件为false时触发异常。

断言可在程序运行条件不满足时直接报错,无需等待程序崩溃。

语法格式如下:

assert expression

其等价于:

if not expression:
    raise AssertionError

assert后也可紧跟参数:

assert expression [, arguments]

其等价于:

if not expression:
    raise AssertionError(arguments)

以下实例判断当前系统是否为Linux,若不满足条件则直接触发异常,后续代码不再执行:

import sys
assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
# 接下来要执行的代码

# Traceback (most recent call last):
#    File "C:/PycharmProjects/untitled/run.py", line 2, in 
#      assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"
#  AssertionError: 该代码只能在 Linux 下执行

到此这篇关于Python异常处理的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。