更改子类的返回类型

2024-06-24 13:07:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个基类(BaseClass),它使用基类(BaseType)的对象进行操作。我想要一个子类(ChildClass),它继承自基类,但使用子类型(ChildType)的对象进行操作

有没有一种方法可以在没有类型暗示错误的情况下实现这一点

考虑下面的代码:

from dataclasses import dataclass
@dataclass
class BaseType:
    name: str

@dataclass
class ChildType(BaseType):
    favoriteColor: str

class BaseClass:
    def __init__(self, myThing: BaseType):
        self.myThing = myThing
    def get_my_thing(self) -> BaseType:
        return self.myThing

class ChildClass(BaseClass):
    def __init__(self, myThing: ChildType):
        self.myThing = myThing
        self.do_something_super_complicated()
    def do_something_super_complicated():
        color = self.myThing.favoriteColor
        # do complicated things with color

现在,get_my_thing()的返回类型为ChildType。我怎样才能证明这是事实?例如,我不想通过以下操作获得类型提示错误:

cc = ChildClass(ChildType(name="bob", favoriteColor="red"))
print(cc.get_my_thing().favoriteColor)
# This causes a type hint error because return type of get_my_thing is BaseType which does not have favoriteColor

如果执行以下操作,仍会出现类型提示错误:

class ChildClass(BaseClass):
    def __init__(self, myThing: ChildType):
        self.myThing = myThing
    def get_my_thing(self) -> ChildType:
        return super().get_my_thing() 
#The return type of super().get_my_thing() is BaseType so this causes a type hint error

Tags: self类型getreturnmydefclassthing
1条回答
网友
1楼 · 发布于 2024-06-24 13:07:14

该类型提示错误中有值-值BaseType不一定是值ChildType。具体地说,如果BaseType是Car,而ChildType是Tesla,super().get_my_thing()in ChildClass返回一些Car,但您正试图将其作为特斯拉进行特殊处理

从您的示例中,似乎希望对某个类进行建模,该类采用泛型类型(必须是BaseType的子类)并具有将泛型类型作为其返回类型的方法get_my_thing。您可以考虑定义一个类,如下所示:

from dataclasses import dataclass
from typing import Generic, TypeVar

@dataclass
class BaseType:
    name: str

@dataclass
class ChildType(BaseType):
    favoriteColor: str

T = TypeVar('T', bound=BaseType)

class MyClass(Generic[T]):
    def __init__(self, myThing: T):
        self.myThing = myThing
    def get_my_thing(self) -> T:
        return self.myThing

class BaseClass(MyClass[BaseType]):
    pass

class ChildClass(MyClass[ChildType]):
    pass


base_type = BaseType("Bob")
base_instance = BaseClass(base_type)
base_instance.get_my_thing().name               # OK

child_type = ChildType("Bob", "blue")
child_instance = ChildClass(child_type)
child_instance.get_my_thing().name              # OK
child_instance.get_my_thing().favoriteColor     # OK

类型提示在我的编辑器上工作(VS代码,使用Pylance语言服务器检查类型提示)

相关问题 更多 >