什么是正确的方法来检查一个对象是否是打字。通用?

我试图编写验证类型提示的代码,为了做到这一点,我必须找出注释是什么类型的对象。 例如,考虑这个片段应该告诉用户期望什么样的价值:

import typing

typ = typing.Union[int, str]

if issubclass(typ, typing.Union):
    print('value type should be one of', typ.__args__)
elif issubclass(typ, typing.Generic):
    print('value type should be a structure of', typ.__args__[0])
else:
    print('value type should be', typ)

这应该打印“值类型应该是(int,str)”之一,但相反,它会抛出一个异常:

Traceback (most recent call last):
  File "untitled.py", line 6, in <module>
    if issubclass(typ, typing.Union):
  File "C:Python34libsite-packagestyping.py", line 829, in __subclasscheck__
    raise TypeError("Unions cannot be used with issubclass().")
TypeError: Unions cannot be used with issubclass().

isinstance也不起作用:

>>> isinstance(typ, typing.Union)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:Python34libsite-packagestyping.py", line 826, in __instancecheck__
    raise TypeError("Unions cannot be used with isinstance().")
TypeError: Unions cannot be used with isinstance().

什么是正确的方法来检查typ是否是一个typing.Generic

如果可能,我希望看到一个由文档或PEP或其他资源支持的解决方案。 通过访问未记录的内部属性“工作”的“解决方案”很容易找到。 但更有可能的是,它会变成一个实现细节,将在未来的版本中发生变化。 我正在寻找“正确的方式”来做到这一点。


您可能正在寻找__origin__

# * __origin__ keeps a reference to a type that was subscripted,
#   e.g., Union[T, int].__origin__ == Union;`
import typing

typ = typing.Union[int, str]

if typ.__origin__ is typing.Union:
    print('value type should be one of', typ.__args__)
elif typ.__origin__ is typing.Generic:
    print('value type should be a structure of', typ.__args__[0])
else:
    print('value type should be', typ)

>>>value type should be one of (<class 'int'>, <class 'str'>)

我能找到的最好的证据来倡导使用这种无证的属性,这是来自Guido Van Rossum(2年前)的令人放心的引用:

我可以推荐的最好的方法是使用__origin__ - 如果我们要改变这个属性,那么仍然需要其他方法来访问相同的信息,并且很容易让你的代码出现__origin__ 。 (我不会担心__origin__变化, __origin__不是__extra__ 。您也可以查看内部函数_gorg()_geqv() (显然,这些名称不会成为任何公共API的一部分,但它们的实现非常简单和概念上有用)。

文档中的这个警告似乎表明大理石中没有任何设置:

如果核心开发人员认为有必要,可能会添加新功能,甚至可能会在次要版本之间改变API。


我认为,你可以做的最多的是在变量上使用typ在其上使用typing.get_type_hints ,并从返回的__annotations__ like字典中提取所需的信息。

PEP-484说:

get_type_hints() ,一个实用函数,用于从函数或方法中检索类型提示。 给定一个函数或方法对象,它会返回一个与__annotations__格式相同的字典,但__annotations__原始函数或方法定义的上下文中的前向引用(作为字符串文本给出)作为表达式求值。

26.1.7。 类,函数和装饰者说:

在运行时, isinstance(x, T)会引发TypeError 。 通常, isinstance()issubclass()不应与类型一起使用。

但是,PEP-526在'非目标'中说:

尽管该提议伴随着用于注释的运行时检索的typing.get_type_hints标准库函数的扩展,但变量标注并不是针对运行时类型检查而设计的。 第三方软件包将不得不被开发来实现这样的功能。

链接地址: http://www.djcxy.com/p/821.html

上一篇: What's the correct way to check if an object is a typing.Generic?

下一篇: angular get image data and again append it to FormData