从抽象基类派生的类实例的Python类型注释

2024-06-24 12:59:12 发布

您现在位置:Python中文网/ 问答频道 /正文

假设已经创建了一个抽象基类MembershipClass。多个类派生自抽象基类,例如FirstClassSecondClass

我希望在函数中使用类型注释,该函数接受从MembershipClass派生的任何类作为参数。如果有少量派生类(例如2个),则应该可以:

from typing import Union
def MyFunc(membership_obj: Union[FirstClass, SecondClass]) -> None:
   ...

有没有一种方法可以为membership_obj创建一个类型提示,本质上说它的类型是从MembershipClass派生的任何类,而不必在类型注释中指定每个可能的派生类

我看到了两种可能的解决办法:

  1. TypeVar
from typing import TypeVar
BaseType = TypeVar('BaseType', bound=MembershipClass)
def MyFunc(membership_obj: BaseType) -> None:
   ...

  1. Direct use of ABC
def MyFunc(membership_obj: MembershipClass) -> None:
   ...

这两种方法都可以接受吗


Tags: 函数fromnoneobj类型defmyfunc基类
1条回答
网友
1楼 · 发布于 2024-06-24 12:59:12

看起来这两种解决方案都可以工作,尽管mypy消息略有不同。考虑下面的示例(我在内联中添加了MyPy错误):

from abc import ABC
from typing import TypeVar


class Base(ABC):
    pass


class Sub(Base):
    pass


BaseType = TypeVar("BaseType", bound=Base)


def MyFunc(c: Base) -> None:
    pass


def MyFunc2(c: BaseType) -> None:
    pass


if __name__ == "__main__":
    b = Base()
    s = Sub()

    MyFunc(b)
    MyFunc(s)
    MyFunc(3)  # main.py:30: error: Argument 1 to "MyFunc" has incompatible type "int"; expected "Base"

    MyFunc2(b)
    MyFunc2(s)
    MyFunc2(3) # main.py:34: error: Value of type variable "BaseType" of "MyFunc2" cannot be "int"

尽管如此,我认为第二种方法更具可读性和直观性。我认为TypeVar更适合于generics(这并不是说如果你想的话就不应该使用它)

相关问题 更多 >