pau*_*l23 6 python type-hinting pycharm
好吧,我正在考虑一个有几个孩子的基类的情况。我有一个函数,该函数接受基类对象的列表,并返回包含这些对象的新列表。
现在,如果我显然要使用子类,则返回的是这些子类对象的列表:考虑以下简单情况:
from typing import Sequence, List, TypeVar
class BaseClass:
def __init__(self, data=None, *args, **kwargs):
super().__init__()
self.CanCalculate = True
if data is None:
data = []
self.CanCalculate = False
self._mydata = list(data)
self.multiplier = 1
@property
def data(self):
return self._mydata
class ChildClass(BaseClass):
def sum_mul_data(self):
return self.multiplier * sum(self.data)
class SecondChildClass(BaseClass):
def sum_div_data(self):
return sum(self.data) / self.multiplier
def myFun(input: Sequence[BaseClass]) -> List[BaseClass]:
out = []
for n, i in enumerate(input):
if i.CanCalculate:
i.multiplier = 10**n
out.append(i)
return out
childs = [ChildClass([1,2,3,4]), ChildClass(), ChildClass([1,2,3,4])]
t = myFun(childs)
for idx in t:
print(idx.sum_mul_data())
childs = [SecondChildClass([1,2,3,4]), SecondChildClass(), SecondChildClass([1,2,3,4])]
t = myFun(childs)
for idx in t:
print(idx.sum_div_data())
Run Code Online (Sandbox Code Playgroud)
合法代码:但是pycharm(和标准类型提示)在静态代码分析期间显示错误:“未解析的属性引用” @ idx.sum_mul_data()
现在,显然这是由于pycharm认为该函数的返回类型为“ BaseClass”的类型-而不是子级。那么我该怎么说:“返回与输入相同的类型”?
我尝试使用typevar:,T = TypeVar("T", BaseClass)尽管给出了一个实际错误,但不能在中使用单个约束TypeVar。有趣的是,T = TypeVar("T", BaseClass, ChildClass)确实使用了工作,并且pycharm正确推断了sum_div_data的类型(提示)。
您应该使用具有上限的typevars:do T = TypeVar('T', bound=BaseClass)而不是T = TypeVar('T', BaseClass)。
细节:
当您执行类似操作时T = TypeVar('T', ClassA, ClassB, ClassC...),您将创建一个具有值限制的类型变量。也就是说,您坚持认为它T必须完全是您列出的类之一。
这就是为什么T = TypeVar('T', ClassA)不允许这样做的原因:typevar只能等于一个类,因此您最好直接使用ClassA类型。
当您执行类似操作时T = TypeVar('T', bound=ClassA),您将创建一个具有上限的类型变量。您坚持认为T必须是ClassA或其任何子类。