我有一个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