注释抽象 class 的构造函数以使 Mypy 开心的正确方法是什么?
What is the right way of annotating constructor of abstract class to make Mypy happy?
我有一个抽象基础 class BsaeFoo
,我的数据 class 继承自 ChildFoo
。
from abc import ABCMeta
from typing import Dict, Any, TypeVar, Type
from dataclasses import dataclass
Foo = TypeVar("Foo", bound="BaseFoo")
class BaseFoo(metaclass=ABCMeta):
@classmethod
def from_dict(cls: Type[Foo], data: Dict[str, Any]) -> Foo:
init_data = {key: data.get(key, None) for key in cls.__annotations__}
return cls(**init_data)
@dataclass
class ChildFoo(BaseFoo):
x: int
y: int
运行 Mypy 给我
main.py:12: error: Too many arguments for "BaseFoo"
Found 1 error in 1 file (checked 1 source file)
from_dict
将是子数据 classes 的替代构造函数。它根据 cls.__annotations__
属性读取输入字典,因此它不会在子 classes 中引发。至于 BaseFoo
本身,检查初始化没有意义,因为它是抽象的 class.
如何在不使用 # type: ignore
的情况下使 BaseFoo.from_dict
通过 Mypy?
在BaseFoo
中添加__init__
的显式定义
class BaseFoo(ABC):
def __init__(self, **kwargs: Any) -> None:
raise NotImplementedError
@classmethod
def from_dict(cls: type[Foo], data: Dict[str, Any]) -> Foo:
init_data = {key: data.get(key, None) for key in cls.__annotations__}
return cls(**init_data)
我有一个抽象基础 class BsaeFoo
,我的数据 class 继承自 ChildFoo
。
from abc import ABCMeta
from typing import Dict, Any, TypeVar, Type
from dataclasses import dataclass
Foo = TypeVar("Foo", bound="BaseFoo")
class BaseFoo(metaclass=ABCMeta):
@classmethod
def from_dict(cls: Type[Foo], data: Dict[str, Any]) -> Foo:
init_data = {key: data.get(key, None) for key in cls.__annotations__}
return cls(**init_data)
@dataclass
class ChildFoo(BaseFoo):
x: int
y: int
运行 Mypy 给我
main.py:12: error: Too many arguments for "BaseFoo"
Found 1 error in 1 file (checked 1 source file)
from_dict
将是子数据 classes 的替代构造函数。它根据 cls.__annotations__
属性读取输入字典,因此它不会在子 classes 中引发。至于 BaseFoo
本身,检查初始化没有意义,因为它是抽象的 class.
如何在不使用 # type: ignore
的情况下使 BaseFoo.from_dict
通过 Mypy?
在BaseFoo
__init__
的显式定义
class BaseFoo(ABC):
def __init__(self, **kwargs: Any) -> None:
raise NotImplementedError
@classmethod
def from_dict(cls: type[Foo], data: Dict[str, Any]) -> Foo:
init_data = {key: data.get(key, None) for key in cls.__annotations__}
return cls(**init_data)