python - Python:关闭资源期间报告错误的最佳实践
问题描述
在 Python 中报告关闭资源时发生的错误的最佳实践是什么?
特别是,如果我实现__enter__
and __exit__
,我可以使用
with my_library.connect(endpoint) as connection:
connection.store_data("...")
但是,如果关闭我的连接并保持更改失败,例如由于网络中断,我该怎么办?我知道从技术上讲我可以从内部引发错误,__exit__
但这是 Python 中的最佳实践/惯用语吗?或者我应该提供一个单独的persistChanges
方法,让__exit__
所有错误都被吞下,然后在文档中写“如果你不打电话persistChanges
,你可能会在错误情况下丢失你的更改”?
我的具体用例是:我正在向其他开发人员提供 Python API,我想知道如何处理这种“关闭资源时出错”的情况,以便我的 API 遵循 Python 最佳实践/满足使用我的库的 Python 开发人员的期望.
解决方案
我建议为您的库制作一个自定义错误/警告类。这可以非常非常简单。已经存在一组可以扩展的内置异常。根据您上面的描述,我建议扩展RuntimeError
如下:
class MyLibraryConnectionError(RuntimeError):
pass
或者,如果您只想发出警告,请使用ResourceWarning
以下命令:
class MyLibraryConnectionWarning(ResourceWarning):
pass
还有一个RuntimeWarning
可以扩展以获得类似效果。
如果您觉得ResourceWarning
, RuntimeWarning
, 并且RuntimeError
没有准确地描述异常,您也可以让它们直接从Exception
or继承Warning
,这取决于您是否希望它们仅在开发人员模式(警告)下被标记,或者如果您想要完整的异常功能。
您可以像任何其他异常一样抛出这些:
throw MyLibraryConnectionError("The underlying resource failed to close")
throw MyLibraryConnectionWarning("The underlying resource failed to close")
甚至捕获您的依赖项引发的异常:
def __exit__(...):
try:
# potentially dangerous code with connections
underlyingConnection.close()
except TheErrorYouSeeThrown as e: # you can probably make this Exception instead of TheErrorYouSeeThrown. The more specific the better, so you don't accidentally catch random errors you didn't mean to.
throw MyLibraryConnectionError(e.message) # or whatever this needs to be, depending on the thrown exception type
然后您的用户可以像这样实现:
try:
with my_library.connect(endpoint) as connection:
connection.store_data("...")
except my_library.MyLibraryConnectionError as e:
# handle appropriately, or ignore
except Exception as e:
# Handle other errors that happen, that your library doesn't cause.
推荐阅读
- haskell - 使用 where/let 子句 Haskell 创建一个列表
- excel - Laravel 导出 Excel 不返回 excel 文件
- c++11 - 如何在其他函数中更新 void** 的值,并将其保存到另一个函数中?
- python - Paramiko-expect,超时
- hyperledger-fabric - Hyperledger Fabric 开发和部署工具
- python - 如何在 ROBOT FRAMEWORK 中生成随机浮点值
- c++ - Arduino Autonmous 汽车 if 语句(超声波)
- node.js - 从浏览器获取网络服务器
- sql - 如何通过将参数传递给oracle pl / sql中的where子句来获取多条记录
- mysql - 使用串联名称过滤结果但不在表格中显示名称