情况是这样的。我正在尝试减少项目中样板代码的数量。这是设置的简化版本。
from __future__ import annotations
import dataclasses
import typing as t
import types
_Self = t.TypeVar("_Self", bound="A")
class A:
"""Base class for all classes"""
@classmethod
def create(cls: type[_Self], *args, **kwargs) -> _Self:
return cls(*args, **kwargs)
def do_something(self) -> None:
"""a 'void' method"""
pass
class B(A):
"""A secondary base class for the future dataclasses; NOTE: inheritance from A!"""
T = t.TypeVar("T", bound=B)
TCallable = t.Callable[[type], type[T]]
def decorator(**kwargs) -> TCallable:
"""A decorator for reducing boilerplate"""
def _decorator(cls: type) -> type[B]:
return types.new_class(
cls.__name__,
(
dataclasses.dataclass(**{"frozen": True, "kw_only": True, **kwargs}(cls),
B,
),
)
return _decorator
@decorator(repr=False)
class Test:
"""This is an implementation of the dataclass, subclassed from B, subclassed from A"""
name: str
def __repr__(self) -> str:
return self.name
def do_something_else(self) -> None:
self.do_something() # <- not recognized by pyright
问题是我的静态类型检查器无法识别
class A
实例中解析顺序顶部的 class Test
中的方法。
我在 VSCode 中使用 Pylance/Pyright。
编辑以纠正装饰器中的错误
首先,我应该注意它可以在没有装饰器的情况下实现,如下所示:
@dataclasses.dataclass(frozen = True, kw_only = True, repr=False)
class Test(B):
"""This is an implementation of the dataclass, subclassed from B, subclassed from A"""
name: str
def __repr__(self) -> str:
return self.name
def do_something_else(self) -> None:
self.do_something()
但是我们假设,出于某种原因它需要存在。此示例假设您只是想避免多次输入
frozen
和 kw_only
:
from __future__ import annotations
import dataclasses
import typing as t
_Self = t.TypeVar("_Self", bound="A")
class A:
"""Base class for all classes"""
@classmethod
def create(cls: type[_Self], *args, **kwargs) -> _Self:
return cls(*args, **kwargs)
def do_something(self) -> None:
"""a 'void' method"""
pass
class B(A):
"""A secondary base class for the future dataclasses; NOTE: inheritance from A!"""
@t.dataclass_transform()
def decorator(**kwargs):
def _decorator(cls: type) -> type[B]:
return dataclasses.dataclass(**{"frozen": True, "kw_only": True, **kwargs})(cls)
return _decorator
@decorator(repr=False)
class Test(B):
"""This is an implementation of the dataclass, subclassed from B, subclassed from A"""
name: str
def __repr__(self) -> str:
return self.name
def do_something_else(self) -> None:
self.do_something()
继承方面目前不可能添加到类型中,这就是为什么我让它从 B 继承。总的来说,这可能是更好的实践,因为它使继承结构更清晰。不过,最终可能可以使用
Intersection
进行打字。希望这有用!