我在python3.5的新类型提示/类型模块中玩了一下,试图找到一种方法来确认提示类型是否等于变量的实际类型,并遇到了一些让我相当惊讶的事情。
>>> from typing import List
>>> someList = [1, 2, 3]
>>> isinstance(someList, List[str])
True
继续寻找一种方法来比较变量和它的暗示类型,我也尝试了这个:
>>> anotherList = ["foo", "bar"]
>>> type(anotherList) is List[str]
False
有人能解释为什么前者的计算结果是True
吗?
继续,是否有一种合理的方法来检查变量的类型是否等于来自类型模块的类型?
isinstance
不做真正的PEP 484类型检查。文档附带说明了这一点:
一般情况下,
isinstance()
和issubclass()
不宜与类型一起使用。
typing
模块,以及它所基于的collections.abc
和abc
模块,使用了大量的__instancecheck__
和__subclasscheck__
魔法,使isinstance
和issubclass
行为合理。但他们做得不够支持你的案子。他们的目标也不是支持它。
是否有一种合理的方法来检查变量的类型是否等于来自typing模块的类型?
您不是在寻找类型相等。正如您自己注意到的,[1, 2, 3]
的类型是list
,它的不等于 List[str]
,也不等于List[int]
。您正在寻找类型检查,这要复杂得多。
考虑一下:
def my_function():
# ... 1000 lines of very complicated code ...
print(isinstance(my_function, Callable[[], int]))
你希望这个程序输出什么?您不能期望isinstance
在运行时挖掘my_function
并推断它总是返回int
。这在Python中是不可行的。您要么需要一个能够访问my_function
结构的"编译"时类型检查器,要么需要显式类型注释,或者最可能的是—两者都需要。