Python中引发IOError异常的最佳实践

4
我正在编写一个小型的Python接口,以通过sysfs读取DS18B20传感器的温度。除了温度之外,还可以读取CRC校验和的状态。为了触发CRC错误,我决定利用IOError
sn = "28-000005589697"  # sensor serial number
# file containing information of temperature and if CRC is valid: 
fname = "sys/bus/w1/devices/" + sn + "/w1_slave"
with open(fname, 'f') as f: 
...
raise IOError("Invalid CRC in {}!".format(sn))

据我所知,IOError 包含以下成员:messagefilenameerrnostrerror。然而在我的方法中,只使用了 message。看起来我漏掉了什么。
那么,在引发 IOError 异常时,怎样才能使其与其他错误(如磁盘已满或文件未找到等)更好地融合呢?最佳实践是什么?

你不应该使用 IOError,因为它不是一个 I/O 问题(你仍然可以读取数据),而是完整性问题(你读取的数据不正确或已损坏)。相反,应该定义 CRCErrorIntegrityError 或其他相关错误类型。 - Stefano Sanfilippo
@Stefano,这可能是最直接的解决方案。下一个问题是,从“BaseException”或“EnvironmentError”派生“IntegrityError”是否有意义,后者被描述为“可以发生在Python系统之外的异常的基类”。我知道这有点哲学,但我已经有了一些硬件项目,在那里我最终得到了一个相当混乱的错误层次结构。 - Dietrich
1个回答

4
您知道 filename,它是您正在阅读和计算CRC的文件。对于errnostrerror,我会从libc中定义的错误列表中进行选择。这就是大多数IOErrors的原因所在,因此为了保持一致性,我们要将此实现细节予以保留。选择哪些值有些随意(并且不完全独立于操作系统),我会尝试传达我的问题的一般含义,而不是过于具体。您可以选择其中之一(注释应为strerror):
EIO          5  /* I/O error */
EINVAL      22  /* Invalid argument */

过于具体的“假”libc错误可能会让人们在调试问题时走错方向。

顺便提一下,我查阅了这个列表,里面列出了已存在的errno值。


1
谢谢指点 - 我希望有一种比读取所有错误代码并选择最合适的更结构化的方法(以不同类型的错误需要不同的处理方式为例,例如,对于超时或CRC错误,重试是有意义的;但对于磁盘已满的错误则不然)。供参考:在Python中,可以通过“os”模块检索errnos列表的描述,方法是键入“[(k,v, os.strerror(k)) for k,v in os.errno.errorcode.items()]”。 - Dietrich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接