捕获特定函数调用的坏签名错误

2 投票
2 回答
1047 浏览
提问于 2025-04-18 09:17

我可能会有这样的代码:

def sum(a, b):
    return a + b

# User chooses function and parameters
function = sum
params = {"a": 5, "b": 3}

try:
    ret = sum(**params)
    print(ret)
except TypeError:
    # Function called with bad signature
    print("Wrong parameters for the chosen function!")
except:
    print("Internal error")

模块的用户会选择一个函数和一组参数字典。这个函数会被执行,用户会被告知如果参数不正确(因为用错误的参数调用函数会引发一个 TypeError 错误)。如果函数内部有问题,导致其他类型的错误出现,就会显示“内部错误”。

嗯,差不多。 但是,sum 函数可能也会因为内部调用错误而引发 TypeError。这种情况应该被视为内部错误。

我该如何处理这种情况,以便在 sum 函数被错误参数调用时捕捉到这个错误,并避免在函数内部引发 TypeError 时出现误报呢?

2 个回答

1

你有四个选择,但没有一个是完美的。

  • 手动调整所有的函数。

  • 使用函数自省来检查参数是否对这个函数有效。不过,这种方法可能会漏掉一些特殊情况,比如被通用装饰器包裹的函数。可以参考ntrrgc的回答,了解如何检查。

  • 检查错误信息。这可以捕捉到内部错误,但如果函数错误地调用了其他函数,这种方法就不一定有效了。

  • 就这样过下去吧。

3

PEP-0362 定义了一个叫做签名对象的东西,这个东西很有用。在 Python 3.3 及以上版本中,它是默认包含的,不过对于早期版本,可以使用一个回溯版本

下面是使用签名对象来检查参数是否正确的代码:

import sys
try:
    from inspect import signature
except ImportError:
    from funcsigs import signature

def sum(a, b):
    return a + b

# User chooses function and parameters
function = sum
params = {"a": 5, "b": 3}

try:
    # Check signature
    signature(function).bind(**params)
except TypeError:
    # Function called with bad signature
    print("Wrong parameters for function!")
    sys.exit(1)

# Signature is fine, continue...
try:
    ret = sum(**params)
    print(ret)
except:
    # Exception in function
    print("Internal error")

撰写回答