python - 异常处理的良好实践
问题描述
我想就 Python 中的异常处理的良好实践提供一些建议。
如果我以一个使用该库的简单程序socket
为例,我会有这样的代码块:
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('127.0.0.1', 6666))
except OSError as e:
if e.errno == 98:
log.error('Address already in use')
else:
raise
我的问题是:像这样处理异常是否有趣,因为我可以简单地引发它并且堆栈跟踪将打印在我的日志文件中?
我的观点是,如果没有通过特定进程处理异常(例如调用特定函数,或更新某些上下文或其他),那么我不会仅仅记录一条消息,而这正是我所拥有的引发异常。
但同时,我认为干净的代码应该捕获可能出现的明显异常,并尝试在通用except
子句中处理所有其他类型的异常,以防万一。
您对这个特定问题有何看法?
非常感谢。
解决方案
想象一下你的try
语句在一个循环体中,它尝试绑定到各种地址,直到你找到一个可用的地址。在这种情况下,如果地址已经在使用中,则通过确认它发生并转移到下一个可能的地址来完全“处理”异常。
addresses_to_try = [...]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
for address in addresses_to_try:
try:
sock.bind(address, 6666)
break
except OSError as e:
if e.errno == errno.EADDRINUSE:
log.warning("%s already in use, trying the next address", address)
else:
raise
else:
raise OSError(errno.EADDRINUSE, "All addresses in use")
处理异常也可能意味着您知道无法从错误中恢复,并且您绝对需要退出程序。重新引发异常只是表示您不知道如何从此处的错误中恢复,但调用堆栈中更高级别的人可能知道如何,并且您正在给他们这样做的机会。
try:
sock.bind(address, 6666)
except OSError as e:
if e.errno == errno.EADDRINUSE:
sys.exit("The only and only possible address is not available")
else:
log.error("Something when wrong binding to %s", address)
log.error("Maybe someone else can do something about it.")
raise
推荐阅读
- java - 如何为 Java HTTPS *server* 配置 SSL 密码套件?
- r - 更新函数内的模型因子水平无法正常工作
- angular - 角度错误 TS2304:找不到名称“配置”
- ffmpeg - 使用 FFmpeg 报告重复的帧
- python - 自我模型上的多对多:如何向此关系添加新实例
- rascal - 优先级声明是否可以消除替代词汇之间的歧义?
- sublimetext3 - 在 ST3 Win10 中显示/隐藏选项卡的键盘快捷键
- angularjs - 何时使用 AngularJS `$onInit` Life-Cycle Hook
- jquery - 如何从 Jquery 克隆的 div 中编写删除脚本
- spring-mvc - @RequestBody 不绑定复杂对象