【问题标题】:How not to return to a calling function?如何不返回调用函数?
【发布时间】:2014-05-09 10:40:19
【问题描述】:

如果在被调用函数中发生某个事件,在 python 中是否有办法不返回调用函数。比如……

def acquire_image(sdkobject):

    ret = sdkobject.PrepareAcquisition()
    error_check(ret)

    ret = sdkobject.StartAcquisition()
    error_check(ret)

error_check 是一个检查返回码以查看 sdk 调用是否有错误的函数。如果这是一条错误消息,那么我不想返回获取和映像,而是转到另一个函数来重新初始化 sdk 并从头开始。有没有一种pythonic的方式来做到这一点?

【问题讨论】:

  • 返回错误码,从调用函数调用重新初始化代码。
  • @thefourtheye 这是否意味着我必须在每个 sdk 函数调用中都有一个 if 语句?
  • sdkobject 函数返回错误代码而不是引发异常的事实已经相当不符合 Python 风格。
  • @chepner sdkobject 只是原始 c++ sdk 的 python 包装器。它在输入和输出中反映了 c++。
  • good 包装器不会强制 Python 程序使用 C++ 编码约定。 (就此而言,为什么 C++ API 也不使用异常?)

标签: python function error-handling return


【解决方案1】:

如果出现问题,让您的 error_check 函数引发异常(如 SDKError),然后在 while 循环中运行所有命令。

class SDKError(Exception):
    pass

# Perhaps define a separate exception for each possible
# error code, and make a dict that maps error codes to the
# appropriate exception.

class SDKType1Error(SDKError):
    pass

class SDKType5Error(SDKError):
    pass

sdk_errors = {
    1: SDKType1Error,
    5: SDKType5Error,
}

# Either return, if there was no error, or raise
# the appropriate exception
def error_check(return_code):
    if return_code == 0:
        return   # No error
    else:
        raise sdk_errors[return_code]


# Example of how to deal with specific SDKErrors subclasses, or a generic
# catch-all SDKError
def acquire_image(sdkobject):

    while True:
        try:
            # initialize sdk here
            error_check(sdkobject.PrepareAcquisition())    
            error_check(sdkobject.StartAcquisition())
        except SDKType1Error:
            # Special handling for this error
        except SDKError:
            pass
        else:
            break

【讨论】:

  • 这已经很有帮助了。如何编写 error_check 函数来触发异常。是否需要返回异常?
  • 我将添加一个示例(最初忘记这样做)。
【解决方案2】:

返回错误并使用if条件判断返回值是否有错误,如果有则从调用函数调用重新初始化代码。

【讨论】:

    【解决方案3】:

    使用return 获得快乐的场景

    返回调用函数通过简单的returnreturn response完成。

    当一切顺利时,使用它来解决典型的代码运行问题。

    出错时抛出异常

    如果出现问题,请致电raise Exception()。在许多情况下,您的代码不必显式执行此操作,它会自行引发异常。

    您甚至可以使用自己的异常实例,并使用它们向调用者传递有关问题所在的更多信息。

    我花了一些时间来学习这种方法,它使我的编码变得更简单、更短。

    不要关心你的调用代码会用它做什么

    如果有问题,让您的函数完成任务或失败。

    试图在您的函数中考虑客户责任会弄乱您的代码,并且无论如何都不是完整的解决方案。

    要避免的事情

    忽略谁在呼唤你

    在 OOP 中,这是客户端匿名原则。只处理请求,不在乎谁在打电话。

    不要尝试使用异常来代替返回值

    有时,人们使用异常可以将一些信息传递给调用者。但这是相当反模式(总是有例外。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      • 2013-09-17
      • 1970-01-01
      • 2017-08-14
      • 2017-12-14
      • 1970-01-01
      相关资源
      最近更新 更多