为什么用户定义的异常会打印模块名称?

Why does a user-defined exception print the module name?

提问人:gberenzy 提问时间:11/3/2023 最后编辑:gberenzy 更新时间:11/5/2023 访问量:37

问:

我正在学习 Python,并正在创建我的第一个装饰器,用于检查修饰函数是否传递了正确类型的对象,如果没有,则引发异常。我创建了一个名为来处理此问题的子类。TypeErrorTypeNotFoundError

# strict.py

from inspect import signature, _empty

class TypeNotFoundError(TypeError):
    pass

def strict_types(original_function):

    def wrapper(*args, **kwargs):
        sig = signature(original_function)
        for param, arg in zip(sig.parameters.values(), args):
            try:
                arg_type = param.annotation
                if arg_type == _empty:
                    raise TypeNotFoundError(f"Type annotation not found in function signature")
            except TypeNotFoundError as e:
                print(str(e))
                raise
            if isinstance(arg, arg_type) or isinstance(arg, type(None)):
                continue
            else:
                raise TypeError(f"Parameter '{param.name}' must be {arg_type}")
        return original_function(*args, **kwargs)
    return wrapper


@strict_types
def test_hint(string: str):
    print(type(string))

@strict_types
def test_no_hint(string):
    print(type(string))

在 REPL 中调用或直接提高时,它会打印 .为什么它包含模块名称?为什么回溯显示引发错误的行,而其他内置错误则不显示?test_no_hintTypeNotFoundErrorstrict.TypeNotFoundError

>>> import strict as s
>>> s.test_no_hint("I'm not dead yet")
Type hint not found in function signature
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/file_path/strict.py", line 15, in wrapper
    raise TypeNotFoundError(f"Type hint not found in function signature")
strict.TypeNotFoundError: Type hint not found in function signature

在这里使用 - 子句也感觉有点勉强。只使用这样的语句有什么问题吗:tryexceptraise

if arg_type == _empty:
    raise TypeNotFoundError(f"Type annotation not found in function signature")

有没有更好/更标准的模式来做到这一点?

我尝试在 REPL 中导入异常并将异常导入其自己的模块,看看是否有任何影响(它没有)。我似乎在文档中找不到任何提及。我发现这个 SO 问题很相似,但没有回答为什么会发生这种情况或如何省略它。

Python 异常 错误处理 python-decorators 类型检查

评论

1赞 tripleee 11/3/2023
为什么它准确地告诉你异常是什么是一个问题?在许多情况下,这很有帮助,因为它可以让你更好地查明错误的来源。
0赞 Matthias 11/3/2023
关于 try-except-raise 的问题:不要在包装器中捕获异常。只需提出异常即可。我认为没有必要抓住异常并重新提出它,但也许我错过了一些东西。
0赞 gberenzy 11/5/2023
@Matthias 这也是我的想法,我正在探索的内容似乎建议尝试使用 try 和 除非在处理异常时,但我同意这里似乎是多余的和不必要的
0赞 gberenzy 11/5/2023
@tripleee 这本身不是问题,我只是想了解为什么在其他自定义异常示例中未显示模块名称时,我会看到模块名称显示给我。我确实认为没有模块名称会更干净。
0赞 user2357112 11/5/2023
“在其他自定义异常示例中未显示模块名称时” - 这些示例是什么?如果您不向我们展示未为自定义异常打印模块名称的示例,我们将无法告诉您您的代码与这些示例之间有什么不同。

答: 暂无答案