11

在尝试更新我的代码以符合 PEP-484(我使用的是mypy0.610)时,我遇到了以下报告:

$ mypy mymodule --strict-optional --ignore-missing-imports --disallow-untyped-calls --python-version 3.6

myfile.py:154: error: Signature of "deliver" incompatible with supertype "MyClass"

我的课:

from abc import abstractmethod

from typing import Any


class MyClass(object):

@abstractmethod
def deliver(self, *args: Any, **kwargs: Any) -> bool:
    raise NotImplementedError

我的文件.py:

class MyImplementation(MyClass):

[...]

    def deliver(self, source_path: str,
                dest_branches: list,
                commit_msg: str = None,
                exclude_files: list = None) -> bool:

        [...]

        return True

我肯定在这里做错了什么,但我不太明白是什么:)

任何指针将不胜感激。

4

3 回答 3

14
@abstractmethod
def deliver(self, *args: Any, **kwargs: Any) -> bool:
    raise NotImplementedError

这个声明并不意味着子类可以给出deliver他们想要的任何签名。子类deliver方法必须准备好接受超类deliver方法将接受的任何参数,因此您的子类deliver必须准备好接受任意位置或关键字参数:

# omitting annotations
def deliver(self, *args, **kwargs):
    ...

你的子类deliver没有那个签名。


如果所有子类都应该具有deliver您编写的相同签名MyImplementation,那么您也应该给出MyClass.deliver相同的签名。如果您的子类将具有不同的deliver签名,那么此方法可能不应该真正存在于超类中,或者您可能需要重新考虑您的类层次结构,或者给它们相同的签名。

于 2018-06-23T16:44:50.820 回答
0

Callable[..., Any]您可以通过使用等来解决问题type: ignore

from typing import Callable

class MyClass(object):
    deliver: Callable[..., bool]
    @abstractmethod
    def deliver(self, *args, **kwargs): # type: ignore
        raise NotImplementedError
于 2021-12-05T05:21:06.623 回答
-3

也许你应该这样解决它:

  1. 定义不带参数的抽象方法:

    class MyClass:
        @abstractmethod
        def deliver(self) -> bool:
            raise NotImplementedError
    
  2. 在实现中从以下位置获取所有数据self

    class MyImplementation(MyClass):
        def __init__(
                self,
                source_path: str,
                dest_branches: list,
                commit_msg: str = None,
                exclude_files: list = None
        ) -> None:
            super().__init__()
            self.source_path = source_path
            self.dest_branches = dest_branches
            self.commit_msg = commit_msg
            self.exclude_files = exclude_files
    
        def deliver(self) -> bool:
            # some logic
            if self.source_path and self.commit_msg:
                return True
            return False
    

这样,您将拥有完全兼容的方法声明,并且仍然可以根据需要实现方法。

于 2019-05-30T08:47:32.527 回答