rea*_*oy7 2 python python-dataclasses
我遇到一种情况,我需要将变量 a、b 和 c 一起存储在数据类中,其中c = f(a,b)a、b 可以发生变化。c打印对象时,I 需要与 a 和 b 一起显示,并且c只能通过更改a或来更改b。我认为做到这一点的最好方法就是c通过财产创造价值。
我尝试使用的最小示例:
@dataclass
class Demo:
a:int
b:int
c:int = field(init=False)
@property
def c(self) -> int:
return self.a * self.b
Run Code Online (Sandbox Code Playgroud)
但是,调用此结果会导致AttributeError: can't set attribute. 我怀疑代码试图将 c 设置为field(init=False),但失败了,因为 c 没有设置器。
我考虑过的选项(不包括我尝试过的使代码以不同方式崩溃的替代方案):
c在 init 中
@c.setter什么都不做的
sys._getframe().f_back.f_code则在 setter 中使用会引发错误__init__c在 中创建__post_init__,并用于dataclasses.replace修改 a 和 b。
Demo(嗯,实际的东西,不是最小的例子)要求它是可变的。尾注:
@c.setter
def c(self, val):
caller = sys._getframe().f_back.f_code.co_name
if caller != '__init__':
raise ValueError # or some other error
Run Code Online (Sandbox Code Playgroud)
如果您想c成为计算属性,则完全取出该c字段并保留该属性:
@dataclass
class Demo:
a:int
b:int
@property
def c(self) -> int:
return self.a * self.b
Run Code Online (Sandbox Code Playgroud)
字段用于存储数据,但c不应该如此。
如果你想出c现在 中repr,你必须__repr__自己编写方法。如果以后的代码需要c显示在 中fields,那么您可能需要在更深层次上重新编写代码,并且可能切换到dataclasses.