什么是正确的方法来检查一个对象是否是打字。通用?
我试图编写验证类型提示的代码,为了做到这一点,我必须找出注释是什么类型的对象。 例如,考虑这个片段应该告诉用户期望什么样的价值:
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
标准库函数的扩展,但变量标注并不是针对运行时类型检查而设计的。 第三方软件包将不得不被开发来实现这样的功能。
上一篇: What's the correct way to check if an object is a typing.Generic?