python - Python 3.5+ 中类型提示的动态检查

标签 python python-3.x duck-typing python-typing

这个问题在这里已经有了答案:





How to use type hints in python 3.6?

(3 个回答)


去年关闭。




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也解决了问题。所以这是2个积极的解决方案。然而,pydantic似乎更适合数据建模,并且对他们的验证装饰器提出了一些强烈的警告:

The validate_arguments decorator is in beta, it has been added to pydantic in v1.5 on a provisional basis. It may change significantly in future releases and its interface will not be concrete until v2. Feedback from the community while it's still provisional would be extremely useful; either comment on #1205 or create a new issue.

最佳答案

我喜欢 this 中给出的答案线程,所以我会在这里给出:

You can use annotations in Python3, which might help you get some benefits of static typing.

However if static typing were to be completely enforced in Python, then it won't be Python anymore. It's a duck-typed dynamic language, and would loose all dynamism as a result. If you really intend to use a statically-typed language, you are better off not using Python.


并引用 PEP 563 中的话:

Python will remain a dynamically typed language, and the authors have no desire to ever make type hints mandatory, even by convention


就个人而言,有些工具在运行时使用类型注释进行类型检查和验证,因为可以通过 __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)
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)

关于python - Python 3.5+ 中类型提示的动态检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63343360/

相关文章:

python - 在使用 django-admin.py 或 manage.py 时存在差异

Python(17874,0x111e92dc0)malloc : can't allocate region

python - 将 NLTK 的通用标记集与非英语语料库结合使用

python - 瘦身一个xml

java - 如何使用 Groovy 或其他一些 JVM 语言对 Java 对象进行 Duck 类型

python - 使用 **kwargs 实现向后兼容

python - tf.Session() 是否应该在 tf.Graph() 的上下文中?

python-3.x - Pandas 使用除 apply 之外的许多条件添加新列的替代方法

.net - .NET 中的泛型和 Duck-Typing XML?

clojure - Clojure 中的类型系统