在尝试将我的代码更新为符合PEP-484标准时(我正在使用mypy
0.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"
MyClass:
from abc import abstractmethod
from typing import Any
class MyClass(object):
@abstractmethod
def deliver(self, *args: Any, **kwargs: Any) -> bool:
raise NotImplementedError
myfile.py:
class MyImplementation(MyClass):
[...]
def deliver(self, source_path: str,
dest_branches: list,
commit_msg: str = None,
exclude_files: list = None) -> bool:
[...]
return True
我肯定在这里做错了,但是我不太明白:)
任何指针将不胜感激。
答案 0 :(得分:4)
@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
签名,则此方法可能实际上不应该在超类中,或者您可能需要重新考虑类层次结构或给它们相同的签名。
答案 1 :(得分:0)
也许您应该按照以下方式解决它:
定义不带参数的抽象方法:
class MyClass:
@abstractmethod
def deliver(self) -> bool:
raise NotImplementedError
在实现中,从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
这样,您将拥有完全兼容的方法声明,并且仍然可以根据需要实现方法。