从类型中提取数据
extracting data from typing types
我在使用 Python 中的 typing
类型时遇到一些问题,除了类型提示:
>>> from typing import List
>>> string_list = ['nobody', 'expects', 'the', 'spanish', 'inqusition']
>>> string_list_class = List[str]
现在我想
- 检查
string_list
是否符合string_list_class
.
- 检查
string_list_class
是否是一个列表。
- 如果是,请检查 class,即
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
documentation 对此也没有太大帮助。此外 API 似乎不打算以这种方式使用,但是,我需要使用该功能。
四处游荡
我发现回答 2 的一种方法是,
>>> type(string_list_class)
<class 'typing._GenericAlias'>
虽然我无法访问 _GenericAlias
我可以自己构建它:
>>> _GenericAlias = type(List[str])
>>> isinstance(string_list_class, _GenericAlias)
True
然而,这似乎根本不是一个好的解决方案,它也会为其他 class 产生 True
,例如 Collection
。
对于 1. 和 3. 我可以想象将一些东西与 repr(type(string_list))
和 repr(string_list_class)
一起破解,然后以某种方式将该字符串与某些东西进行比较,但这也不是一个好的解决方案。
但一定有更好的方法来做到这一点
检查变量是否符合输入对象
要检查 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
检查键入对象的类型参数
要检查class,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
我在使用 Python 中的 typing
类型时遇到一些问题,除了类型提示:
>>> from typing import List
>>> string_list = ['nobody', 'expects', 'the', 'spanish', 'inqusition']
>>> string_list_class = List[str]
现在我想
- 检查
string_list
是否符合string_list_class
. - 检查
string_list_class
是否是一个列表。 - 如果是,请检查 class,即
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
documentation 对此也没有太大帮助。此外 API 似乎不打算以这种方式使用,但是,我需要使用该功能。
四处游荡
我发现回答 2 的一种方法是,
>>> type(string_list_class)
<class 'typing._GenericAlias'>
虽然我无法访问 _GenericAlias
我可以自己构建它:
>>> _GenericAlias = type(List[str])
>>> isinstance(string_list_class, _GenericAlias)
True
然而,这似乎根本不是一个好的解决方案,它也会为其他 class 产生 True
,例如 Collection
。
对于 1. 和 3. 我可以想象将一些东西与 repr(type(string_list))
和 repr(string_list_class)
一起破解,然后以某种方式将该字符串与某些东西进行比较,但这也不是一个好的解决方案。
但一定有更好的方法来做到这一点
检查变量是否符合输入对象
要检查 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
检查键入对象的类型参数
要检查class,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