mypy 错误:向抽象方法添加类型时无法使用抽象属性实例化抽象类
Posted
技术标签:
【中文标题】mypy 错误:向抽象方法添加类型时无法使用抽象属性实例化抽象类【英文标题】:mypy error: Cannot instantiate abstract class with abstract attributes when adding types to an abstract method 【发布时间】:2021-12-29 03:49:01 【问题描述】:我有一个类,我想为其添加类型提示,如下所示:
import yaml
class TestClass(dict):
@classmethod
def load(cls, fname) -> "TestClass":
return cls(yaml.safe_load(""))
@property
@abc.abstractmethod
def test(self):
raise
当我在仅包含此类的模块上运行 mypy 时,我收到以下错误消息:
error: Cannot instantiate abstract class 'TestClass' with abstract attribute 'test'
根据我从其他帖子中了解到的情况,这与在执行加载方法时实例化“测试”方法有关。有没有办法单独使用 typehints 来解决这个问题,还是我需要在这里调整我的代码?
【问题讨论】:
你能澄清你想要做什么吗?在不是abc.ABC
的类上使用abc.abstractmethod
没有多大意义。
【参考方案1】:
mypy 告诉你的是TestClass.load(...)
会失败,因为它会尝试创建抽象类TestClass
的实例。
我们可以通过要求cls
可以用任何yaml.safe_load
返回的东西来解决这个问题(我在这里假设dict
),并返回一个TestClass
的实例:
from typing import Callable
import abc
import yaml
class TestClass(dict):
@classmethod
def load(cls: Callable[[dict], TestClass], fname) -> "TestClass":
return cls(yaml.safe_load(""))
@property
@abc.abstractmethod
def test(self):
raise
请注意,TestClass.load("foo")
现在也将通过类型检查。这在某种程度上是公平的,因为它在运行时也很好,直到您在创建的实例上调用test()
。我认为这可能是 mypy 如何实现协议的限制。
【讨论】:
def load(cls: Any, fname)
在这种情况下应该和cast
ing 做同样的事情。
@MisterMiyagi 你能更清楚地解释为什么会出现这个错误吗?调用 return cls(yaml.safe_load("") 时,我们用 yaml 返回的字典实例化类,但这与抽象方法到底有什么关系?为什么通过预先实例化 cls 来解决这个问题?
@Thomas 你能解释一下吗?我不太明白为什么只用抽象方法返回类的实例会导致问题
@hhhh 你知道什么是抽象类吗?
@Thomas 据我了解,这就像一个超类,其方法在不同的子类中使用以上是关于mypy 错误:向抽象方法添加类型时无法使用抽象属性实例化抽象类的主要内容,如果未能解决你的问题,请参考以下文章
使用 mypy 进行类型检查,我无法弄清楚为啥会发生此错误 [关闭]