python类型提示,返回与输入相同的类型

python类型提示,返回与输入相同的类型,python,pycharm,type-hinting,Python,Pycharm,Type Hinting,我在考虑一个案例,我有一个有(几个)孩子的基础班。我有一个函数,它获取基类对象的列表,并返回一个包含这些对象的新列表 现在,如果我显然要使用子类,返回是这些子类对象的列表:考虑下面的小事例: from typing import Sequence, List, TypeVar class BaseClass: def __init__(self, data=None, *args, **kwargs): super().__init__() self.

我在考虑一个案例,我有一个有(几个)孩子的基础班。我有一个函数,它获取基类对象的列表,并返回一个包含这些对象的新列表

现在,如果我显然要使用子类,返回是这些子类对象的列表:考虑下面的小事例:

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())
法律代码:但是pycharm(以及标准类型提示)在静态代码分析期间显示错误: “未解析属性引用”@
idx.sum\u mul\u data()

显然这是因为pycharm认为函数的返回类型是“BaseClass”,而不是子函数。那么我该如何声明:“返回与输入相同的类型”


我尝试使用一个typevar:
T=typevar(“T”,BaseClass)
,尽管这给出了一个实际的错误,一个contint不能在
typevar
中使用。有趣的是,使用
T=TypeVar(“T”,BaseClass,ChildClass)
确实有效,pycharm正确地推导了sum\u div\u数据的类型(提示)。

您应该使用带有上限的TypeVar: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
    ,或其任何子类


你似乎已经解决了自己的问题。文档似乎说
T=TypeVar(“T”)
会给你一个完全通用的类型提示,正如你所看到的,你的
T=TypeVar(“T”,基类,子类)
是有效的。@quamrana但这意味着
myFun
的位置至少了解一个这样的子类。-最重要的是,为什么会有对
ChildClass
的引用,这似乎是完全武断的:为什么不引用
SecondChildClass
或其他什么?