考虑以下因素:
@dataclass
class Base:
prop1: str
prop2: str
@dataclass
class Derived1(Base):
isValid: bool = self.prop2.casefold() == 'valid'
@dataclass
class Derived2(Base):
isOpen: bool = self.prop1.casefold() == 'open'
isShared :bool
在这个特定的示例中,仅对 2 个 props 进行基类化,但为了论证而想象它是 773 个 props。 某些东西,某个地方,你不关心什么和在哪里,会返回一个
Base
的实例。现在,您可能希望将其提升为 Derived1
,保留所有现有值。通常,据我所知,如果我想要一个 Derived1
或 Derived2
类 id 的实例,则必须初始化该实例,然后在 Derived 的 __init__
或 __post_init__
中手动为所有 773 个 prop 写入分配。这是疯狂的。经过一番研究后,我发现了一个很好的建议可以解决这个问题。相反,我使用普通类并通过 __dict__
技巧从现有基础实例更新道具:
class Derived(Base):
isOpen: bool = False
def __init__(self, base: Base):
self.__dict__.update(base.__dict__)
self.isOpen = (str(base.currStatus).casefold() == 'open')
虽然这似乎工作得很好,但我不断地从
pylint
那里得到一个严重错误,那就是需要有超级。这就是我感到困惑的地方 - 我需要这里有一个超级吗?问题是,对于 super
,我又回到了原点,我必须手动重新初始化所有 700 多个道具……这是我首先想要避免的。
这整件事看起来非常愚蠢 - 这是我们正在谈论的Python,我很容易看出它在类方面存在这个问题(其他一些语言在 30 年前就解决了这个问题)。
使用
asdict
。
from dataclasses import dataclass, asdict
@dataclass
class Base:
prop1: str
prop2: str
# make it a property so you don't have to import `asdict`
# in classes that import this class
@property
def asdict(self) -> dict:
return asdict(self)
@dataclass
class Derived1(Base):
isValid: bool = self.prop2.casefold() == 'valid'
@dataclass
class Derived2(Base):
isShared :bool
isOpen: bool = self.prop1.casefold() == 'open'
base = Base('hello', 'world')
derived = Derived2(**base.asdict, isShared=False)