Python协议不兼容警告
我想要给我的纯混入类(MyMixin
)加个提示,说明它希望父类里有一个叫做 get_context_data
的方法。
class HasViewProtocol(Protocol):
kwargs: dict
@abstractmethod
def get_context_data(self, **kwargs) -> dict:
pass
class MyMixin(HasViewProtocol):
def get_context_data(self, **kwargs) -> dict:
return super().get_context_data(**kwargs) | {
"extra_data": "bla"
}
这里是Pycharm的检查结果:
type of 'get_context_data' is incompatible with 'HasViewProtocol`
- 使用协议(protocols)来标注我对父类的期望是否合适?
- 为什么
get_context_data
和HasViewProtocol
不兼容?
1 个回答
2
根据定义,抽象方法是没有具体实现的,直接调用这样的一个方法通常意味着代码有问题。但是在 MyMixin
的 get_context_data()
方法中,你正好在做这样的事情。
class MyMixin(HasViewProtocol):
def get_context_data(self, **kwargs) -> dict:
return super().get_context_data(**kwargs) | {
....
你试图调用父类的抽象方法,所以我知道的所有代码检查工具都会把这个标记为错误。没错,我明白 MyMixin
是为了和那些已经实现了 get_context_data()
方法的类一起使用的,但在这个时候,代码检查工具并不知道这一点。而且不仅仅是 PyCharm,其他的代码检查工具也会有类似的反馈。比如,mypy
会报告:
错误:通过 super() 调用 "HasViewProtocol" 的抽象方法 "get_context_data" 的实现是危险的 [safe-super]
实际上,即使你去掉了装饰器,mypy
也会因为只有 pass
的实现而抱怨。
至于 PyCharm 提示的 get_context_data
的类型与 "HasViewProtocol" 不兼容的警告,这很可能与它如何理解代码有关。但在我看来,这个提示本身并不太对,也不太符合上下文,所以我建议你把这个问题反馈给 JetBrains,可以通过 PyCharm 的 bug 跟踪器 来报告。