我不喜欢听到Mypy抱怨函数签名,但是我不知道如何解决这个问题。
我正在构建一个包,它将被几个程序使用。我有一个interum的子类(FWIW,称为_Event),它包含许多相关的属性和方法。_Event永远不会被直接使用,因为它不包含任何成员,但是几个不同的程序使用_Event的不兼容子类(AlphaEvent, BetaEvent等),这些子类定义了Enum的实际成员(即实际事件)。每个子类中只有一个成员是公共的,它被称为END。既然你不能子类enum与成员,分别定义在每个子类(所以_Event没有端员,但AlphaEvent。和BetaEvent结束。存在)。
我有几个函数利用_Event的子类。我有一对需要访问END成员的属性,但对所有实例都是通用的。所以它们包含一个签名:
def generic_event_func(events: _Event):
...
events.END.action = <expr>
MyPy用"error: "_Event" has no attribute "END"
标记上面的最后一行代码确实如此,但是子类确实如此。我如何注释函数签名以消除此错误?
我最近遇到了一个类似的问题,最后使用ABC进行了重构。我不确定你是否有重构的自由,但也许它能在某种程度上有所帮助:
from abc import ABC, abstractmethod
from enum import Enum
class Event(Enum):
a = EventA
b = EventB
c = EventC
class AbstractEvent(ABC):
@abstractmethod
def action(self):
pass
class EventA(AbstractEvent):
def action(self):
....
event_cls = Event["a"].value
event: Union[EventA, EventB, EventC] = event_cls()
event.action()
我(还)不是一个可选的静态类型的人,但是像下面这样的东西可能会工作:
from typing import Any
class _Event(IntEnum):
END: Any
End
现在是类型提示,但实际上并不存在,因此不会干扰_Event
的子类化。