[英]Extend dataclass' __repr__ programmatically
假设我有一个带有 set 方法的数据类。 如何扩展 repr 方法,以便在调用 set 方法时它也会更新:
from dataclasses import dataclass
@dataclass
class State:
A: int = 1
B: int = 2
def set(self, var, val):
setattr(self, var, val)
前任:
In [2]: x = State()
In [3]: x
Out[3]: State(A=1, B=2)
In [4]: x.set("C", 3)
In [5]: x
Out[5]: State(A=1, B=2)
In [6]: x.C
Out[6]: 3
我想要的结果
In [7]: x
Out[7]: State(A=1, B=2, C=3)
dataclass
装饰器使您可以快速轻松地构建具有特定字段的类,这些字段在您定义 class 时预先确定。 但是,您打算使用 class 的方式与数据类的用途不太匹配。 您希望能够在 class 已经存在之后动态添加新字段,并让它们使用各种方法(如__init__
、 __repr__
和大概__eq__
)。 这几乎消除了使用dataclass
的所有好处。 相反,您应该编写自己的 class 来执行您想要的操作。
这是一个快速而肮脏的版本:
class State:
_defaults = {"A": 1, "B": 2}
def __init__(self, **kwargs):
self.__dict__.update(self._defaults)
self.__dict__.update(kwargs)
def __eq__(self, other):
return self.__dict__ == other.__dict__ # you might want to add some type checking here
def __repr__(self):
kws = [f"{key}={value!r}" for key, value in self.__dict__.items()]
return "{}({})".format(type(self).__name__, ", ".join(kws))
这与您从types.SimpleNamespace
获得的内容非常相似,因此您可能只能使用它(尽管它不执行默认值)。
您可以将您的set
方法添加到此框架中,但在我看来,这似乎是您已经用来实现它的内置setattr
function 的不必要重复。 如果调用者需要动态设置属性,可以自己调用setattr
。 如果属性名称是常量,他们可以使用普通的属性赋值语法来代替s.foo = "bar"
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.