5

我有一个做某事的父类和两个以正交方式包装方法的子类。当我尝试合并两个子类时,mypy 抱怨以下错误。

基类“Foo”中“run”的定义与基类“Bar”中的定义不兼容

这两个类如何“不兼容”以及如何修改我的代码以安抚mypy?我可以不做吗

class Parent:
    def run(self, a, b):
        pass


class Foo(Parent):
    def run(self, a, b, foo=None, **kwargs):
        print('foo', foo)
        super().run(a, b, **kwargs)


class Bar(Parent):
    def run(self, a, b, bar=None, **kwargs):
        print('bar', bar)
        super().run(a, b, **kwargs)


class C(Foo, Bar):
    pass
4

2 回答 2

1

一个简单的解决方法是制作foobar仅关键字参数:

class Parent:
    def run(self, a, b):
        pass


class Foo(Parent):
    def run(self, a, b, *, foo=None, **kwargs):
        print('foo', foo)
        super().run(a, b,  **kwargs)


class Bar(Parent):
    def run(self, a, b, *, bar=None, **kwargs):
        print('bar', bar)
        super().run(a, b, **kwargs)


class C(Foo, Bar):
    pass

使用位置参数的问题在于mypy,如果您要进行类似 的调用,则无法判断C().run(1,2,3)每个调用应该如何处理3。想C作为一个Foo,应该是值foo。但想想C作为一个Bar,它应该是 的值bar通常,将位置参数添加到覆盖方法的签名是一个坏主意,即使在运行时3将绑定到首先调用的方法的第一个可用参数。

此外,因为没有办法为foobar的实例传递位置参数C,所以无论如何你都必须将它们作为关键字参数传递,所以你不妨这样声明它们。

于 2020-02-09T13:50:25.387 回答
1

Mypy 抱怨只是因为您试图从 Foo 和 Bar 继承 C,它们运行相同的方法,但参数不同。为了让 Mypy 满意,您必须使 Foo 和 Bar 类中的运行函数相同(匹配相同的函数签名),或者不要从它们两者继承类 C。

于 2020-02-09T13:42:48.953 回答