Lar*_*son 6 python duck-typing python-3.x python-typing
该typing
模块在 Python 3.5+ 中实现类型提示。然而,这并没有强制执行,它目前似乎只是为了静态类型检查器(例如 PyCharm )的利益mypy
而存在。我希望它能成为鸭子打字的可行替代方案。
问题:有没有一种方法可以在 Python 3.7+ 中打开动态类型检查,但我在 Google 搜索中没有找到?例如,如果我定义
def greeting(name: str) -> str:
return name
Run Code Online (Sandbox Code Playgroud)
那么这应该在执行时失败:
greeting([12])
Run Code Online (Sandbox Code Playgroud)
我不介意为此检查付出时间代价,因为出于我的目的,我必须使用assert
语句手动实现它,并且类型提示更加简洁和描述性。
更新:下面的评论者指出typen包将为我动态强制执行类型提示。因此,这是一个肯定的答案,它将更新旧问题的答案,该问题的范围仅限于 Python 3.6,并且答案是否定的。我已经验证规范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
Run Code Online (Sandbox Code Playgroud)
唯一的缺点是每个函数都需要进行修饰才能获得行为,而不是有一个开关来打开所有功能。
更新 2:下面的回答还指出pydantic也解决了这个问题。这是两个正解。然而,pydantic
似乎更适合数据建模,并且对其验证装饰器有一些强烈的警告:
validate_arguments 装饰器处于beta阶段,它已在 v1.5 中临时添加到 pydantic 中。它在未来的版本中可能会发生重大变化,并且其界面直到 v2 才会具体化。来自社区的反馈(尽管它仍然是临时的)将非常有用;对 #1205 发表评论或创建一个新问题。
我喜欢这个帖子中给出的答案,所以我将在这里给出:
您可以在 Python3 中使用注释,这可能会帮助您获得静态类型的一些好处。
然而,如果在 Python 中完全强制执行静态类型,那么它就不再是 Python 了。这是一种鸭子类型的动态语言,因此会失去所有的活力。如果您确实打算使用静态类型语言,那么最好不要使用 Python。
并引用 PEP 563 中的话:
Python 仍将是一种动态类型语言,即使按照惯例,作者也不希望强制类型提示
就个人而言,有些工具在运行时使用类型注释进行类型检查和验证,因为注释可以通过__annotations__
属性访问。例如,我在项目中使用的pydantic 。但它有其自身的特点,例如,它会在可能的情况下尝试进行隐式类型转换。
一些例子:
from pydantic import validate_arguments, ValidationError, BaseModel
...
...
... @validate_arguments
... def sum_foo(a: int, b: int) -> int:
... return a + b
...
sum_foo("Hello", 1)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "pydantic/decorator.py", line 25, in pydantic.decorator.validate_arguments.wrapper_function
File "pydantic/decorator.py", line 107, in pydantic.decorator.ValidatedFunction.call
File "pydantic/main.py", line 346, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for SumFoo
a
value is not a valid integer (type=type_error.integer)
Run Code Online (Sandbox Code Playgroud)
class data(BaseModel):
... a: int = 0
... b: int = 1
...
d = data(a=0, b="Hello")
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "pydantic/main.py", line 346, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for data
b
value is not a valid integer (type=type_error.integer)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3385 次 |
最近记录: |