参数化泛型中 isinstance 和 issubclass 从 python 3.5 到 3.6 的 mypy 差异
mypy differences in isinstance and issubclass from python 3.5 to 3.6 in parameterized generics
在我从 python 3.5 升级到 python 3.6 之前,这个有效:
import typing
issubclass(list, typing.List[int]) # returns True
isinstance([1, 2 ,3], typing.List[int]) # returns True
现在在 python 3.6 中,这两个都会引发以下异常:
TypeError: Parameterized generics cannot be used with class or instance checks
这是新的预期行为还是错误?如果有意如何执行上面代码在 python 3.6 中所做的检查?
这是故意的,你不应该将 类 与 typing
中定义的类型混合,至少,根据我的理解,这是它的要点。问题 #136 Kill __subclasscheck__
which also introduced this change. The commit message 中对此进行了大量讨论,还提到了 isinstance
/subclass
检查将如何引发 TypeError
s:
Using isinstance()
or issubclass()
raises TypeError
for almost everything. There are exceptions: [...]
您可以比较而无需指定泛型类型的包含类型,即:
isinstance(list, typing.List[int])
但那是你能做的最好的 afaik。
如果您想在 python 中获得更好的类型安全性,您的选择是有限的。我采用的一种技术是子类化 list 或 dict 而不覆盖任何属性、方法等
class ListInts(list):
pass
new_obj = ListInts()
new_obj += [1, 2, 3, 4, 5, 6]
print(isinstance(new_obj, ListInts)
在我从 python 3.5 升级到 python 3.6 之前,这个有效:
import typing
issubclass(list, typing.List[int]) # returns True
isinstance([1, 2 ,3], typing.List[int]) # returns True
现在在 python 3.6 中,这两个都会引发以下异常:
TypeError: Parameterized generics cannot be used with class or instance checks
这是新的预期行为还是错误?如果有意如何执行上面代码在 python 3.6 中所做的检查?
这是故意的,你不应该将 类 与 typing
中定义的类型混合,至少,根据我的理解,这是它的要点。问题 #136 Kill __subclasscheck__
which also introduced this change. The commit message 中对此进行了大量讨论,还提到了 isinstance
/subclass
检查将如何引发 TypeError
s:
Using
isinstance()
orissubclass()
raisesTypeError
for almost everything. There are exceptions: [...]
您可以比较而无需指定泛型类型的包含类型,即:
isinstance(list, typing.List[int])
但那是你能做的最好的 afaik。
如果您想在 python 中获得更好的类型安全性,您的选择是有限的。我采用的一种技术是子类化 list 或 dict 而不覆盖任何属性、方法等
class ListInts(list):
pass
new_obj = ListInts()
new_obj += [1, 2, 3, 4, 5, 6]
print(isinstance(new_obj, ListInts)