1

我不喜欢从 Mypy 收到有关函数签名的投诉,但我不知道如何解决这个问题。

我正在构建一个包,供多个程序使用。我有一个 IntEnum 的子类(FWIW,称为 _Event),它包含许多相关的属性和方法。_Event 从不直接使用,因为它不包含任何成员,但是几个不同的程序使用不兼容的 _Event 子类(AlphaEvent、BetaEvent 等),它们定义了 Enum 的实际成员(即实际事件)。每个子类只有一个成员是通用的,碰巧它被称为 END。由于您不能使用成员对枚举进行子类化,因此它在每个子类中单独定义(因此 _Event 没有 END 成员,但存在 AlphaEvent.END 和 BetaEvent.END )。

我有几个利用 _Event 子类的函数。我有几个需要访问 END 成员的属性,但对所有实例都是通用的。所以它们包含一个签名:

def generic_event_func(events: _Event):
    ...
    events.END.action = <expr>

MyPy 将上面的最后一行代码标记为"error: "_Event" has no attribute "END"

确实如此,但子类确实如此。如何注释函数签名以消除此错误?

4

2 回答 2

0

我(还)不是一个可选的静态输入人员,但类似以下的内容可能会起作用:

from typing import Any

class _Event(IntEnum):
    END: Any

End现在是类型提示,但实际上并不存在,因此不会干扰子类化_Event

于 2021-09-30T15:17:27.167 回答
0

我最近遇到了一个类似的问题,并使用 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()
于 2021-09-30T14:36:54.260 回答