如何正确地向Mixin类添加类型提示?

问题描述 投票:5回答:2

请考虑以下示例。这个例子是人为的,但是在一个可运行的例子中说明了这一点:

class MultiplicatorMixin:

    def multiply(self, m: int) -> int:
        return self.value * m


class AdditionMixin:

    def add(self, b: int) -> int:
        return self.value + b


class MyClass(MultiplicatorMixin, AdditionMixin):

    def __init__(self, value: int) -> None:
        self.value = value


instance = MyClass(10)
print(instance.add(2))
print(instance.multiply(2))

执行时,这将给出以下输出:

12
20

代码有效。

但是在它上面运行mypy会产生以下错误:

example.py:4: error: "MultiplicatorMixin" has no attribute "value"
example.py:10: error: "AdditionMixin" has no attribute "value"

我理解为什么mypy给出了这个结果。但mixin类本身从不使用。它们总是用作额外的超类。

对于上下文,这是一个已在现有应用程序中使用的模式,我正在添加类型提示。在这种情况下,错误是误报。我正在考虑使用mixins重写部分,因为我不是特别喜欢它,并且可能通过重新组织类层次结构来完成相同的操作。

但我仍然想知道这样的事情是如何被恰当地暗示的。

python type-hinting
2个回答
2
投票

我在我的机器上测试过它,希望它对你也有用:

class MultiplicatorMixin:
    value = None # type: int

    def multiply(self, m: int) -> int:
        return self.value * m


class AdditionMixin:
    value = None # type: int

    def add(self, b: int) -> int:
        return self.value + b


class MyClass(MultiplicatorMixin, AdditionMixin):

    def __init__(self, value: int) -> None:
        self.value = value


instance = MyClass(10)
print(instance.add(2))
print(instance.multiply(2))

3
投票

我在this question中看到的一种方法是暗示self属性的类型。与打字包中的Union一起,您可以使用与mixin一起使用的类中的属性,同时仍然为自己的属性提供正确的类型提示:

from typing import Union

class AdditionMixin:

    def add(self: Union[MyBaseClass, 'AdditionMixin'], b: int) -> int:
        return self.value + b


class MyBaseClass:

    def __init__(self, value: int):
        self.value = value

缺点是您必须为每种方法添加提示,这有点麻烦。

© www.soinside.com 2019 - 2024. All rights reserved.