键入检查函数参数是“Pythonic”吗? [关闭]
Posted
技术标签:
【中文标题】键入检查函数参数是“Pythonic”吗? [关闭]【英文标题】:Is it "Pythonic" to type check function arguments? [closed] 【发布时间】:2022-01-05 08:09:01 【问题描述】:来自 C/C++ 背景,我一直对 Python 缺乏强大的类型检查感到失望。因此,它总是引导我编写这种风格的代码:
def function (this_should_be_list, this_should_be_int):
isFristArgList = isinstance(this_should_be_list,list)
if not isFristArgList:
raise Exception("The first argument should be a list!")
isSecondArgInt = isinstance(this_should_be_int,int)
if not IsSecondArgInt:
raise Exception ("The second argument should be an int!")
....
....
....
return
这导致代码更加复杂和臃肿,在我的理解中,这与编写尽可能清晰的代码的“Pythonic 哲学”相反。与这种动态检查方法相反,有人可能会说,如果没有它,function 也会失败并引发一些异常,因此它并没有什么区别,但我认为这真的很难预测(尤其是在具有多个嵌套调用的更大代码库中)是否存在某些极端情况错误,这些错误将使 function 在“表面”上正确执行,但与我们的预期不符。
所以我的问题是,我应该如何在 Python 中解决这个问题? 由于我以前使用 C/C++ 的经验,我是否只是偏向于强类型的“样式”,并且应该只接受 Python 的鸭子类型? 或者,有没有更优雅的方式在 Python 中进行类型检查?
【问题讨论】:
首先你可以使用类型提示来代替。那么就没有规则了:如果您发现有人在滥用您的 API 或者错误消息在他们这样做时很含糊,那么您就可以开始保护您的 API。否则让鸭子打字行动 虽然 python 不支持强类型检查,但它支持类型提示已经有一段时间了,至少 3.5 及更高版本。请参阅文档中的 Support for type hints。 使用 mypy! mypy-lang.org 【参考方案1】:使用类型注释和mypy。这为您提供了静态类型检查的所有好处,并且通常不需要对编写 Python 代码的方式进行重大更改,除了在函数声明中添加注释。
# Annotate your parameters like this:
def function(this_should_be_list: list, this_should_be_int: int):
pass
# Then when you run mypy on your code, it tells you when types don't match:
function([1, 2, 3], 10)
function(10, "foo") # error: Argument 1 to "function" has incompatible type "int"; expected "List[Any]"
# error: Argument 2 to "function" has incompatible type "str"; expected "int"
只需运行 mypy
作为常规测试策略的一部分,类似于验证 C++ 代码是否通过编译时检查的方式。如果这样做,通常不需要进行运行时检查,就像在 C++ 代码中一样。
【讨论】:
感谢您的回答,mypy 看起来是一个非常有用的工具! 运行时检查对用户访问的函数仍然有效。特别是当它们防止错误以不清楚的方式出现或在代码的后面出现时。【参考方案2】:如有必要,可以以 Python 方式完成,但您需要确定 type
是否真正重要。例如,第一个变量 必须 是 list,还是必须是可迭代的?第二个必须是一个int,还是需要一个非零小数部分?
假设这两个问题的答案都是“是”,我会将您的代码修改为:
def function (this_should_be_list, this_should_be_int):
if not hasattr(this_should_be_list, '__iter__'):
raise Exception("The first argument should be an iterable!")
if this_should_be_int%1 != 0:
raise Exception ("The second argument should be integer!")
....
....
....
return
【讨论】:
以上是关于键入检查函数参数是“Pythonic”吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章