请考虑以下示例。这个例子是人为的,但是在一个可运行的例子中说明了这一点:
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重写部分,因为我不是特别喜欢它,并且可能通过重新组织类层次结构来完成相同的操作。
但我仍然想知道这样的事情是如何被恰当地暗示的。
我在我的机器上测试过它,希望它对你也有用:
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))
我在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
缺点是您必须为每种方法添加提示,这有点麻烦。