【问题标题】:python : using type hints to dynamically check typespython:使用类型提示动态检查类型
【发布时间】:2021-12-25 12:44:45
【问题描述】:

python 支持类型提示:

https://docs.python.org/3/library/typing.html

我想知道这些提示是否也可用于在运行时动态强制执行类型。

例如:

class C:

    def __init__(self):
        self.a : int = 0

    def __str__(self):
        return str(self.a)

    @classmethod
    def get(cls,**kwargs):
        c = cls()
        for k,v  in kwargs.items():
            setattr(c,k,v) 
            # ValueError exception thrown here ?
        return c

attrs = {"a":"a"} # developer wanted an int !
c = C.get(**attrs)
print(c)

简而言之,我想避免在get函数中重新输入属性“a”的类型:

    @classmethod
    def get(cls,**kwargs):
        c = cls()
        for k,v  in kwargs.items():
            if k=="a" and not isinstance(v,int):
                raise ValueError()
            setattr(c,k,v) 
        return c

有没有办法“重用”构造函数中给出的“a”应该是一个 int 的信息?

注意:对这个问题的回答表明,至少对于函数的自省参数类型提示可以访问:

How to introspect on PEP 484 type hints?

【问题讨论】:

  • 无运行时强制。线索在术语hint

标签: python type-hinting typing duck-typing


【解决方案1】:

我想知道这些提示是否也可用于在运行时动态强制执行类型。

在某些情况下,使用外部库 - 答案是肯定的。阅读下文。

如果你的实际用例很简单,就像你的 C 类,我会去使用数据类和像 dacite 这样的库。您将无法创建 c2,因为您没有传递 int。
所以 dacite 设法“看到”a 应该是 int 并引发异常

from dataclasses import dataclass
from dacite import from_dict
@dataclass
class C:
  a:int = 0

d1 = {'a':3}

c1: C = from_dict(C,d1)
print(c1)
print(C.__annotations__)

d2 = {'a':'3'}

c2: C = from_dict(C,d2)

输出

C(a=3)
{'a': <class 'int'>}

Traceback (most recent call last):
  File "main.py", line 14, in <module>
    c2: C = from_dict(C,d2)
  File "/opt/virtualenvs/python3/lib/python3.8/site-packages/dacite/core.py", line 68, in from_dict
    raise WrongTypeError(field_path=field.name, field_type=field.type, value=value)
dacite.exceptions.WrongTypeError: wrong value type for field "a" - should be "int" instead of value "3" of type "str"

【讨论】:

  • 感谢您介绍数据类和 dacit。在我将其标记为正确答案之前,我是否可以要求您通过添加 C.__annotations__ 提供对 C 类属性类型的内省进行编辑?
  • @Vince - 你为什么要我这样做?这里的附加值是什么? Actail 元数据来自“字段”(在 dacite 的情况下)——github.com/konradhalas/dacite/blob/…
  • 无论如何.. 我已将其添加到帖子中。 -- print(C.__annotations__)
猜你喜欢
  • 2019-05-10
  • 2018-08-07
  • 2020-11-30
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 2013-09-14
  • 2021-01-15
  • 2023-03-29
相关资源
最近更新 更多