返回该类实例的子类方法的类型注释

时间:2019-07-07 14:12:33

标签: python python-3.x type-hinting mypy python-typing

我有一个MeasurementBase抽象父类,它具有以下功能:(1)公共serialize()deserialize()

我希望在父公共方法上实现通用逻辑,并定义私有的_serialize()_deserialize()抽象。

基类的实现如下:

import json
from abc import ABC, abstractmethod
from typing import Any, Dict, Generic, TypeVar


TMeasurement = TypeVar("TMeasurement")


class MeasurementBase(ABC, Generic[TMeasurement]):

    def serialize(self) -> str:
        properties: Dict[str, Any] = {}
        properties["measurement_name"] = self.__class__.__name__
        properties["value"] = self._serialize()
        return json.dumps(properties)

    @abstractmethod
    def _serialize(self) -> Any:
        pass  # pragma: no cover

    @classmethod
    def deserialize(cls, json_str: str) -> TMeasurement:
        try:
            properties = json.loads(json_str)
            class_name = properties["measurement_name"]
            if cls.__name__ != class_name:
                raise KeyError()

            return cls._deserialize(properties["value"])
        except KeyError:
            raise KeyError()

    @classmethod
    @abstractmethod
    def _deserialize(cls, obj: Any) -> TMeasurement:
        pass  # pragma: no cover

然后,我创建了一个内部状态为_val的新子类,该子类实现了抽象方法:

class MeasurementBaseMock(MeasurementBase["MeasurementBaseMock"]):
    def __init__(self, val: int) -> None:
        self._val = val

    def _serialize(self) -> Any:
        return self._val

    @classmethod
    def _deserialize(cls, obj: int) -> "MeasurementBaseMock":
        return MeasurementBaseMock(obj)

然后,在测试以上内容时:

properties = {"value": 324, "measurement_name": MeasurementBaseMock.__name__}
measurement = MeasurementBaseMock.deserialize(json.dumps(properties))
print(measurement._val)

我遇到以下错误:

error: "TMeasurement" has no attribute "_val"

如何注释_deserialize返回类型以支持typecker?

我尝试过的事情: -我尝试使用TMeasurement = TypeVar("TMeasurement", bound = "MeasurementBase")-没有用,并且出现了更多mypy错误。 -我将状态的所有初始化都移到了父类上-这确实起作用了,但是我更喜欢不使用这种设计。 -我也使用cls注释,但是有相同的错误。

注意: 我正在使用mypy

> mypy --version
mypy 0.660

0 个答案:

没有答案