如何避免在子类中由于属性协方差的警告?



我试图避免在代码示例的最后一行作为注释显示的linter警告。

我明白为什么会这样,我知道我可以忽略它,因为这是Python。但作为一种自我锻炼,我一直在努力想一种合适的方式来避免它,但还没能找到解决办法。

下面是一个代码示例:

class Content(ABC):
def __init__(self, data: Dict):
self._data: Dict = data

class AlertContent(Content):
def __init__(self, alert: Alert):
data: Dict = get_data_from_alert(alert)
super().__init__(data)
self.alert_priority: str = alert.priority

class Envelope(ABC):
def __init__(self, content: Content):
self._content: Content = content

@property
@abstractmethod
def priority(self) -> str:
raise NotImplementedError

class AlertEnvelope(Envelope):
def __init__(self, content: AlertContent):
super().__init__(content)
@property
@abstractmethod
def priority(self) -> str:
return self._content.alert_priority  # Warning: Unresolved attribute reference 'alert_priority' for class 'Content'

你有什么想法吗?

我认为这是一个风格问题,但它是有争议的,因为拥有准确的类型是你的设计的一部分,你实际上不需要super().__init__(content),因为你正在构建一个依赖于AlertContent的具体接口的类,而父类显式地使用更抽象的类型类型的属性,不实现接口。

,

class AlertEnvelope(Envelope):
def __init__(self, content: AlertContent):
self._content: AlertContent = content

考虑到您的目标是什么,可能仍然是DRY代码。

我最终采用了以下解决方案:

class AlertEnvelope(Envelope):
def __init__(self, content: AlertContent):
super().__init__(content)
# Inherited from Envelope
# @property
# def content(self) -> Content:
#     return self._content
def alert_content(self) -> AlertContent:
return cast(AlertContent, self._content) # ** Reasoning below 
@property
@abstractmethod
def priority(self) -> str:
return self.alert_content.alert_priority

**我选择这个解决方案的原因是:

  1. 尽管cast实际上不做任何事情(定义为pass),但它是一种方法,可以让检查器知道输入中发生了变化,因此您不会得到错误。而且,作为pass,它的成本几乎可以忽略不计。
  2. 对于任何读代码的人来说都是显式的。
  3. 模仿你在c++中做的方式,c++是一种硬类型语言,这是我的目标之一,遵循硬类型方法。

最新更新