【问题标题】:How to make only a method generic in a python class如何在 python 类中只使一个方法通用
【发布时间】:2023-01-18 21:13:24
【问题描述】:

我有以下基类来表示字段:

T = TypeVar("T")


@dataclass
class BaseClass(Generic[T]):
    def validate(self, value: T):
        raise NotImplementedError

我还有一个枚举来表示此类的可用实现:

class Types(Enum):
    A = auto()
    B = auto()

    @staticmethod
    def from_instance(instance: BaseClass) -> "Types":
        if isinstance(instance, ClassA):
            return Types.A
        if isinstance(instance, ClassB):
            return Types.B
        raise ValueError("Not supported")

现在,从这些类中,我有几个实现:

@dataclass
class ClassA(BaseClass[str]):
    def validate(self, value: str):
        pass


@dataclass
class ClassB(BaseClass[int]):
    def validate(self, value: int):
        pass

在这个设置之后,我有另一个类来存储BaseClass的列表:

@dataclass
class Container:
    instances: List[BaseClass]

    def get_by_type(self, type: Types) -> List[BaseClass]:
        return [instance for instance in self.instances if type == Types.from_instance(instance)]

最后我有以下代码和以下错误:

def function(fields_from_class_a: List[ClassA]):
    print(fields_from_class_a)


container = Container(instances=[ClassA(), ClassB()])
fields = container.get_by_type(Types.A)


# throws error:
#  Argument 1 to "function" has incompatible type "List[BaseClass[Any]]"; expected "List[ClassA]"
function(fields)

所以我的问题是,我可以修改代码以正确键入方法get_by_type吗?

【问题讨论】:

    标签: python python-3.6 mypy


    【解决方案1】:

    ClassA 仅在运行时映射到Types.from_instance() 中的Types.A。

    你必须使用BaseClass[Literal[Types.A]]而不是ClassA:

    # def function(fields_from_class_a: List[ClassA]):                     # Change this
    def function(fields_from_class_a: List[BaseClass[Literal[Types.A]]]):  # to this
    

    然后输入Container.get_by_type():

    TypesT = TypeVar("TypesT", Literal[Types.A], Literal[Types.B])   # Add this
    
    # def get_by_type(self, type: Types) -> List[BaseClass]:         # Change this
    def get_by_type(self, type: TypesT) -> List[BaseClass[TypesT]]:  # to this
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 2018-07-11
      • 2020-09-09
      相关资源
      最近更新 更多