生成另一个包含原始类的类的类的通用 TypeVar 解决方案

问题描述 投票:0回答:1

我正在尝试提出一个通用的

TypeVar
解决方案,以避免创建不断扩展的
Union
类型注释。这是我目前所拥有的有点人为的 MRE:

from __future__ import annotations
from typing import Union

class CreatedDetails:
    def __init__(self, creator: Union[Creator1, Creator2], new: bool) -> None:
        self.creator = creator
        self.new = new

class Creator1:
    def __init__(self) -> None:
        self.name = "creator1"

    def create(self) -> CreatedDetails:
        return CreatedDetails(creator=self, new=True)

class Creator2:
    def __init__(self) -> None:
        self.name = "creator2"

    def create(self) -> CreatedDetails:
        return CreatedDetails(creator=self, new=False)

creator1 = Creator1()
created = creator1.create()
created.creator.name

这很不错,我的类型检查器可以识别一切:

successful type checker

但是,这依赖于我向

Creator
类型注释添加新的
Ùnion
类。

我尝试过使用通用的

TypeVar

from __future__ import annotations
from typing import TypeVar

CreatorRecord = TypeVar("CreatorRecord")

class CreatedDetails:
    def __init__(self, creator: CreatorRecord, new: bool) -> None:
        self.creator = creator
        self.new = new

class Creator:
    pass

class Creator1(Creator):
    def __init__(self) -> None:
        self.foo = "foo"

    def create(self) -> CreatedDetails:
        return CreatedDetails(creator=self, new=True)

class Creator2(Creator):
    def __init__(self) -> None:
        self.bar = "bar"

    def create(self) -> CreatedDetails:
        return CreatedDetails(creator=self, new=False)

creator1 = Creator1()
created = creator1.create()
created.creator.foo
created.new

但是,类型检查器并不能完全识别这一点:

unsuccessful type checker

我哪里出错了?

python
1个回答
0
投票

CreatedDetails
本身必须是通用的。如果类型检查器只知道
created
CreatedDetails
的实例,则不足以告诉创建它的创建者的特定类型。但通过正确的注释,
CreatedDetails[Creator1]
类型可以提供该信息。

您已经创建了一个泛型构造函数,但您真正需要的是一个泛型类:

from typing import TypeVar, Generic
Creator = TypeVar("Creator")

class CreatedDetails(Generic[Creator]):
    creator: Creator
    new: bool
    def __init__(self, creator: Creator, new: bool) -> None:
        self.creator = creator
        self.new = new

class Creator1:
    def __init__(self) -> None:
        self.foo = "foo"

    def create(self) -> CreatedDetails['Creator1']:
        return CreatedDetails(creator=self, new=True)

class Creator2:
    def __init__(self) -> None:
        self.bar = "bar"

    def create(self) -> CreatedDetails['Creator2']:
        return CreatedDetails(creator=self, new=False)
© www.soinside.com 2019 - 2024. All rights reserved.