【发布时间】:2020-11-30 05:52:24
【问题描述】:
typing 模块在 Python 3.5+ 中实现了类型提示。然而,这不是强制的,它目前似乎只是为了静态类型检查器的利益而存在,例如mypy 和PyCharm。我希望它是duck typing 的可行替代方案。
问题:有没有办法在 Python 3.7+ 中打开动态类型检查,而我在 Google 搜索中没有找到?例如,如果我定义
def greeting(name: str) -> str:
return name
那么这应该在执行时失败:
greeting([12])
我不介意为此检查付出时间代价,因为出于我的目的,无论如何我都必须使用assert 语句手动实现它,并且类型提示更加简洁和描述性。
更新:下面的评论者指出typen 包将为我动态强制执行类型提示。所以这是一个肯定的答案,它将更新older question which was scoped to Python 3.6 and answered in the negative 的答案。我已经验证了规范的 typen 示例按预期工作:
from typen import enforce_type_hints
@enforce_type_hints
def halve_integer(a: int) -> float:
return a / 2
halve_integer(5) # 2.5
halve_integer(5.0) # ParameterTypeError
唯一的缺点是每个功能都需要进行修饰才能获得行为,而不是只有一个开关可以为所有功能打开它。
更新 2:下面的回答还指出 pydantic 也可以解决问题。所以这是两个积极的解决方案。然而,pydantic 似乎更倾向于数据建模,并且对他们的验证装饰器有一些强烈的警告:
validate_arguments 装饰器处于测试版,它已被添加到 pydantic 在 v1.5 中是临时的。它可能会发生重大变化 在未来的版本中,它的接口在 v2 之前不会是具体的。 来自社区的反馈,而它仍然是临时的 非常有用;要么评论 #1205 要么创建一个新问题。
【问题讨论】:
-
我很困惑,鸭子类型与静态类型不同。鸭子类型意味着如果它像鸭子一样嘎嘎叫,那么它就是鸭子。例如, list 和 str 都是可迭代的,因此在这方面它们可以被认为是相同的(如果您正在寻找可迭代的)[尽管这更像是 goose typing]。您也可以考虑使用装饰器或仅在您的代码中执行
if not isinstance(name, str): .... -
你可以复制这个包方法typen
-
Georgy,它的回答是否定的。尽管在解释器中启用它(通过添加与 mypy 中某处相同的代码)是一个如此明显的胜利,但我希望那里有人已经做到了。这就是问题的重点,所以看看某个地方是否有人。这个问题已被其他人提出这一事实意味着它不仅仅是我所需要的。切换到 OCaml 或 Axiom 对我来说是不可行的,我想让它在 Python 中工作。
-
语法悔恨,我必须实现与类型提示相同的效果,但通过在函数参数的类上插入一堆断言语句来进行动态检查。我认为这是鸭子打字的一种形式。
-
语法上的悔恨,是的,TypeN 似乎就是我要找的东西。我必须装饰每个函数以获取行为,这很尴尬,但如果它执行我想要的动态检查,我不介意这样做。您可以将其发布为答案吗?
标签: python python-3.x duck-typing python-typing