Python异常与错误处理机制详解:LBYL与EAFP模式对比
本文深入解析Python异常与错误处理机制,对比LBYL与EAFP两种编程哲学,阐述为何EAFP更受推崇。详细讲解try-except-else-finally结构、异常捕获顺序、空raise重抛、上下文管理器清理资源及contextlib.suppress忽略异常的实战技巧,帮助开发者编写更健壮、简洁的Python代码。
Python异常处理基础
基础知识
LBYL与EAFP模式对比
优先使用异常捕获
LBYL(Look Before You Leap,三思而后行)策略:在执行可能引发错误的操作前,先进行关键条件判断,仅在满足特定条件时才执行后续操作。
EAFP(Easier to Ask for Forgiveness than Permission,先做后求原谅)策略:不进行事前检查,直接执行操作,若发生错误则通过异常处理机制进行捕获和修复。
推荐采用EAFP模式:该方式能使代码结构更加简洁,同时运行效率通常更高。
try语句与异常捕获规范
try语句常用知识
在编写异常处理代码时,应将更精确、具体的except语句放置在前面,而将更通用的父类异常捕获放在后面。
异常类的继承关系示例:BaseException --> Exception --> LookupError --> KeyError。
一旦父类异常被捕获,其子类异常将不再触发对应的except块,因此捕获顺序至关重要。
else与finally分支的使用
使用else分支
try-except-else结构
else分支的作用:仅当try语句块内部未抛出任何异常时,才会执行else分支中的代码逻辑。
注意:与finally不同,如果try语句块中遇到了return或break等中断语句,即使未抛出异常,else分支内的逻辑也不会被执行。
相比之下,finally块中的语句无论try是否抛出异常,也无论是否有return或break,都保证会被执行。
空raise与异常重抛
使用空raise语句
>>> def incr_by_key(d, key):
... try:
... d[key] += 1
... except KeyError:
... print('here')
... raise
...
>>> d = {'a': 1}
>>> incr_by_key(d, 'b')
here
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in incr_by_key
KeyError: 'b'
>>> d['c'] += 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'c'
当在except代码块中使用空的raise语句时,它会原封不动地重新抛出当前捕获的异常,保留原始的异常类型和堆栈信息。
抛出异常,而不是返回错误
上下文管理器与资源清理
使用上下文管理器
__enter__ __exit__
>>> class DummyContext:
... def __init__(self, name):
... self.name = name
... def __enter__(self):
... return f"{self.name} -- something"
... def __exit__(self, exc_type, exc_val, exc_db):
... print("Exiting")
... return False
...
>>> with DummyContext('foo') as name:
... print(f'Name: {name}')
...
Name: foo -- something
Exiting
上下文管理器常用于替代finally语句来清理资源,确保资源在使用后能被正确释放。
在__exit__方法内部执行资源清理操作。
此外,__exit__方法也可以用来对异常进行二次处理然后抛出,或是忽略某种异常等等。
忽略异常的处理技巧
用户忽略异常
一般可以捕获异常后pass
但是也可以:
def __exit__(self, exc_type, exc_val, exc_db):
if exc_type == SomeException:
return True
return False
此外:使用contextlib里面的suppress也可以实现相同的功能
使用contextmanage装饰器
>>> @contextmanager
... def create_con_obj(host, port, timeout=None):
... conn = create_conn(host, port, timeout=timeout)
... try:
... yield conn
... finally:
... conn.close()
yield前面的语句会在进入管理器时执行(类似:__enter__)
之后的逻辑会在退出管理器时执行(类似:__exit__)
到此这篇关于Python异常与错误处理详细讲解的文章就介绍到这了,更多相关Python异常内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













