Python 使用异常返回异常值:这是一种好做法吗?

Python 使用异常返回异常值:这是一种好做法吗?,python,exception,Python,Exception,Python的一种好做法是让函数在大多数时间都不返回任何值,同时通过在存储值的位置引发异常来异常返回有用的值吗 我对此有点不安,因为异常最常被用来表示某种问题,异常的一些属性给出了有关问题的一些细节。在这里,我希望异常实际上是指“这是此函数的异常结果” 为此使用异常是很有诱惑力的,因为(1)这只在异常情况下进行,(2)在Python中这是有效的(如果…不是无,则比使用更有效:…)。另一方面,异常本身不是任何类型错误的标志,只是异常返回值的载体 对于从函数异常返回值,是否有任何反对使用异常的官方建

Python的一种好做法是让函数在大多数时间都不返回任何值,同时通过在存储值的位置引发异常来异常返回有用的值吗

我对此有点不安,因为异常最常被用来表示某种问题,异常的一些属性给出了有关问题的一些细节。在这里,我希望异常实际上是指“这是此函数的异常结果”

为此使用异常是很有诱惑力的,因为(1)这只在异常情况下进行,(2)在Python中这是有效的(如果…不是无,则比使用
更有效:…
)。另一方面,异常本身不是任何类型错误的标志,只是异常返回值的载体

对于从函数异常返回值,是否有任何反对使用异常的官方建议

PS:下面是一个用例:

  • 对象方法根据新数据更新对象的内部状态(它是一个有限状态自动机)
  • 在某个时刻(通常是在获得许多数据点之后),该方法认为必须采取一些操作(在我的例子中:来自对象的一些数据应该存储在数据库中,并且对象的状态被重置为初始状态,以便获得更多数据)
因此,对于方法来说,事件的顺序是:获取数据、更新状态、获取数据、更新状态……啊!我们到达了一个特殊的状态,在那里应该存储有关对象的信息!重置objet的状态并发送相关信息;获取数据、更新状态、获取数据、更新状态……因此,大多数情况下,函数更新对象的内部状态,并且不返回任何内容。异常情况下,它必须发送有关对象的重要信息。

异常可以将任何异常建模为正常的代码流。错误是最常见的用例,但是任何正常返回类型没有意义的情况都可以被视为引发异常的机会

为非错误用例引发异常是非常好的,如果它简化了流程的话

请记住,引发并捕获的
异常
对象本身就是一个值。附加信息是一种完全可以接受的与调用者进行通信的方法,以发出偏离“正常”的信号

我更喜欢异常而不是哨兵值,比如
None
;它使处理变得明确,并且实际上可以导致更干净的处理,并在开发人员忘记处理异常返回值时向他们提供更好的反馈。如果您的代码通常返回一个列表,但在特定的、异常的情况下,您返回
None
,而调用者没有处理它,那么您会在某个地方遇到奇怪的bug
TypeError:“NoneType”对象不可编辑
比显式未处理异常更加神秘。

异常可以将任何异常建模为正常代码流。错误是最常见的用例,但是任何正常返回类型没有意义的情况都可以被视为引发异常的机会

为非错误用例引发异常是非常好的,如果它简化了流程的话

请记住,引发并捕获的
异常
对象本身就是一个值。附加信息是一种完全可以接受的与调用者进行通信的方法,以发出偏离“正常”的信号


我更喜欢异常而不是哨兵值,比如
None
;它使处理变得明确,并且实际上可以导致更干净的处理,并在开发人员忘记处理异常返回值时向他们提供更好的反馈。如果您的代码通常返回一个列表,但在特定的、异常的情况下,您返回
None
,而调用者没有处理它,那么您会在某个地方遇到奇怪的bug
TypeError:“NoneType”对象是不可编辑的
比显式未处理异常更加神秘。

在有结果的异常情况下,您通常希望在调用点处理结果吗?在这种情况下,例外情况是不必要的;只需返回值。在通话时,区别在于:

result = yourFunction()
if result is not None:
    handleExceptionalResult(result)

try:
    yourFunction()
except ExceptionalResult as result:
    handleExceptionalResult(result)

第一点对我来说更清楚

在有结果的例外情况下,您通常希望在调用点处理结果吗?在这种情况下,例外情况是不必要的;只需返回值。在通话时,区别在于:

result = yourFunction()
if result is not None:
    handleExceptionalResult(result)

try:
    yourFunction()
except ExceptionalResult as result:
    handleExceptionalResult(result)

第一点对我来说更清楚

您能否给出一个具体的代码示例,说明您何时可能需要执行此操作?异常模型。。正常流量的例外情况。将其用于任何有意义的带外通信。异常对象本身也是一个值!依我看,在您的用例中,该方法应该返回一个表示“我需要刷新和重置”的bool,或者它应该在内部自动执行刷新和重置。您能否给出一个具体的代码示例,说明您何时可能需要执行此操作?异常模型。。正常流量的例外情况。将其用于任何有意义的带外通信。异常对象本身也是一个值!IMO,在您的用例中,该方法应该返回一个表示“我需要刷新和重置”的bool,或者它应该在内部自动执行刷新和重置。您能否提供一个**接近**的真实示例?@frostnational:the
requests
库可以选择对非2xx或3xx响应代码引发异常。如果您确实引发了异常,请求仍然可以作为异常对象上的属性访问。@frostnational:还有。感谢您提供的示例扫描您提供了一个**几乎**真实世界的示例?@frostnational:
请求
库使引发非2xx或3xx响应代码的异常成为可选。如果你提出一个例外