从输入类型中提取数据

问题描述 投票:0回答:1

我在使用 Python 中的

typing
类型时遇到一些问题,不仅仅是类型提示:

>>> from typing import List
>>> string_list = ['nobody', 'expects', 'the', 'spanish', 'inqusition']
>>> string_list_class = List[str]

现在我愿意

  1. 检查
    string_list
    是否符合
    string_list_class
  2. 检查
    string_list_class
    是否是一个列表。
  3. 如果是这样,请检查班级,
    string_list_class
    是一个列表。

我发现自己无法实现其中任何一个:

>>> isinstance(string_list, string_list_class)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/typing.py", line 708, in __instancecheck__
    return self.__subclasscheck__(type(obj))
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/typing.py", line 716, in __subclasscheck__
    raise TypeError("Subscripted generics cannot be used with"
TypeError: Subscripted generics cannot be used with class and instance checks

>>> issubclass(string_list_class, List)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7/lib/python3.7/typing.py", line 716, in __subclasscheck__
    raise TypeError("Subscripted generics cannot be used with"
TypeError: Subscripted generics cannot be used with class and instance checks

文档对此也没有太大帮助。而且 API 似乎并不打算以这种方式使用,但是,我需要使用该功能

徘徊

我发现回答 2. 的一个方法是,

>>> type(string_list_class)
<class 'typing._GenericAlias'>

虽然我无法访问

_GenericAlias
我可以自己构建它:

>>> _GenericAlias = type(List[str])
>>> isinstance(string_list_class, _GenericAlias)
True

然而,这似乎根本不是一个好的解决方案,它还为其他类(如

True
)产生
Collection

对于 1. 和 3。我可以想象用

repr(type(string_list))
repr(string_list_class)
一起破解某些东西,并以某种方式将该字符串与某些东西进行比较,但这也不是一个好的解决方案。

但是一定有更好的方法来做到这一点

python generics python-typing
1个回答
28
投票

检查变量是否符合类型对象

要检查

string_list
是否符合
string_list_class
,可以使用typeguard类型检查库。

from typeguard import check_type

try:
    check_type('string_list', string_list, string_list_class)
    print("string_list conforms to string_list_class")
except TypeError:
    print("string_list does not conform to string_list_class")

检查类型对象的泛型类型

要检查

string_list_class
是否是列表类型,您可以使用 typing_inspect 库:

from typing_inspect import get_origin
from typing import List

get_origin(List[str]) # -> List

您也可以使用私有

__origin__
字段,但没有稳定性保证。

List[str].__origin__ # -> list

检查类型对象的类型参数

要检查类,

string_list_class
是一个列表,您可以再次使用typing_inspect库。

from typing_inspect import get_parameters
from typing import List

assert get_parameters(List[str])[0] == str

和以前一样,如果你喜欢冒险,还有一个私人领域可以使用

List[str].__args__[0] # -> str
© www.soinside.com 2019 - 2024. All rights reserved.