【发布时间】:2022-02-17 07:14:16
【问题描述】:
如果没有例子,我发现这很难描述。
from typing import List, Type, Optional, cast
class Base():
kind = 'base'
class Child1(Base):
kind = 'child1'
class Child2(Base):
kind = 'child2'
class Child3(Base):
kind = 'child3'
def find_in_list(lst: List[Base], SearchClass: Type[Base]): # Return Optional[??]
for obj in lst: # type: Base
if obj.kind == SearchClass.kind:
return obj
return None
lst = [Child1(), Child2(), Child3()]
def func2(c: Child2) -> None:
assert isinstance(c, Child2)
res2_opt: Optional[Child2] = find_in_list(lst, Child2)
if res2_opt:
func2(res2_opt)
def func3(c: Child3) -> None:
assert isinstance(c, Child3)
res3_opt: Optional[Child3] = find_in_list(lst, Child2) # Should be Error!
if res3_opt:
func3(res3_opt) # Is AssertionError
因为find_in_list 的返回类型太开放,mypy 不认为这有什么问题,但它在运行时正确地命中了断言错误。我试过-> Optional[SearchClass],但它(正确地)没有将其识别为一种类型。
应该可以缩小find_in_list的返回类型的范围,以与SearchClass相同或相同的方式被参数化,这样如果你传入Child2作为参数,你可以将输出限制为Optional[Child2]。如何做到这一点?
【问题讨论】:
-
注意:下一个最接近的 SO 问题是 this one on typing class parameterizations,但这将其扩展到基类和特定子类的参数化。
标签: python mypy python-typing