【发布时间】:2020-03-16 01:02:59
【问题描述】:
假设我有一个数据类:
@dataclass(frozen=True)
class Foo:
id: str
name: str
我希望它是不可变的(因此是 frozen=True),这样 foo.id = bar 和 foo.name = baz 就会失败。但是,我希望能够像这样剥离 id:
foo = Foo(id=10, name="spam")
foo.strip_id()
foo
-> Foo(id=None, name="spam")
我尝试了一些方法,覆盖 setattr,但没有任何效果。有一个优雅的解决方案吗? (我知道我可以编写一个方法来返回一个相同的新冻结实例,除了该 id 已被剥离,但这似乎有点 hacky,它需要我做foo = foo.strip_id(),因为foo.strip_id() 实际上不会更改foo)
编辑:
尽管一些评论者似乎不同意,但我认为“完全可变,随心所欲”和“不可变,除非以这种特殊的、严格控制的方式”之间存在合理的区别
【问题讨论】:
-
你希望它是不可变的,除了你希望它是可变的。您的目标存在根本矛盾。
-
foo = foo.strip_id()是一件非常好的事情。例如,字符串方法就是这样工作的。 -
你不能有可变的、不可变的对象。对不起。选一个。另外:“我知道我可以编写一个方法来返回一个相同的新冻结实例,除了该 id 已被剥离,但这似乎有点 hacky”根本不是 hacky。事实上,这通常被认为是最佳实践,有整个语言可以防止可变状态,这就是对象在这些语言中的工作方式。我会选择那条路线。