Python 3.6:{method} 的签名与超类型 {Class} 不兼容
Python 3.6: Signature of {method} incompatible with super type {Class}
在尝试将我的代码更新为符合 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"
我的班级:
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
我肯定在这里做错了什么,但我不太明白是什么:)
任何指点将不胜感激。
@abstractmethod
def deliver(self, *args: Any, **kwargs: Any) -> bool:
raise NotImplementedError
这个声明并不意味着 subclasses 可以给 deliver
他们想要的任何签名。 Subclass deliver
方法必须准备好接受 superclass deliver
方法会接受的任何参数,所以你的 subclass deliver
必须准备好接受任意位置或关键字参数:
# omitting annotations
def deliver(self, *args, **kwargs):
...
您的子class的deliver
没有那个签名。
如果所有子 class 都应该具有您为 MyImplementation
编写的相同 deliver
签名,那么您也应该给 MyClass.deliver
相同的签名.如果你的 subclasses 将有不同的 deliver
签名,也许这个方法不应该真正在 superclass 中,或者你可能需要重新考虑你的 class层次结构,或给他们相同的签名。
也许你应该这样解决:
定义不带参数的抽象方法:
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
这样您将拥有完全兼容的方法声明,并且仍然可以根据需要实现方法。
您可以使用 Callable[..., Any]
和 type: ignore
解决问题,如下所示。
from typing import Callable
class MyClass(object):
deliver: Callable[..., bool]
@abstractmethod
def deliver(self, *args, **kwargs): # type: ignore
raise NotImplementedError
在尝试将我的代码更新为符合 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"
我的班级:
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
我肯定在这里做错了什么,但我不太明白是什么:)
任何指点将不胜感激。
@abstractmethod
def deliver(self, *args: Any, **kwargs: Any) -> bool:
raise NotImplementedError
这个声明并不意味着 subclasses 可以给 deliver
他们想要的任何签名。 Subclass deliver
方法必须准备好接受 superclass deliver
方法会接受的任何参数,所以你的 subclass deliver
必须准备好接受任意位置或关键字参数:
# omitting annotations
def deliver(self, *args, **kwargs):
...
您的子class的deliver
没有那个签名。
如果所有子 class 都应该具有您为 MyImplementation
编写的相同 deliver
签名,那么您也应该给 MyClass.deliver
相同的签名.如果你的 subclasses 将有不同的 deliver
签名,也许这个方法不应该真正在 superclass 中,或者你可能需要重新考虑你的 class层次结构,或给他们相同的签名。
也许你应该这样解决:
定义不带参数的抽象方法:
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
这样您将拥有完全兼容的方法声明,并且仍然可以根据需要实现方法。
您可以使用 Callable[..., Any]
和 type: ignore
解决问题,如下所示。
from typing import Callable
class MyClass(object):
deliver: Callable[..., bool]
@abstractmethod
def deliver(self, *args, **kwargs): # type: ignore
raise NotImplementedError