[英]how to add values for frozen dataclasses during initialization
I have two dataclasses that I need to add dynamicly generated attribute "code: a lower case version of the name" on both of them我有两个数据类,我需要在它们两个上添加动态生成的属性“代码:名称的小写版本”
for the first one I did我做的第一个
@dataclass()
class FirstClass:
name: str
code: Optional[str] = field(init=False)
def __post_init__(self):
self.code = self.name.lower()
with init=False I don't need to provide it in the constructor, since it's gonna be generated anyway使用 init=False 我不需要在构造函数中提供它,因为无论如何都会生成它
however second class is Frozen because I cache its return since it's too big and too expensive to read everytime但是第二个 class 被冻结了,因为我缓存了它的返回,因为它太大而且每次都读取太贵
@dataclass(frozen=True)
class SecondClass:
name: str
is there anyway to add dynamically generated attribute during init and not post_init because frozen dataclasses are read-only无论如何在init期间添加动态生成的属性而不是post_init,因为冻结的数据类是只读的
so I want to do something like所以我想做类似的事情
@dataclass(frozen=True)
class SecondClass:
name: str
code: str = name.lower()
I'd use a combination of the first approach with a custom creation function:我将第一种方法与自定义创建 function 结合使用:
@dataclass(frozen=True)
class SecondClass:
name: str
code: Optional[str]
def create_second(name):
return SecondClass(name, name.lower())
print(create_second('Me'))
Result:结果:
SecondClass(name='Me', code='me')
One option could be to use object.__setattr__
to bypass the fact that the dataclass is frozen:一种选择是使用
object.__setattr__
绕过数据类被冻结的事实:
from dataclasses import dataclass, field
@dataclass(frozen=True)
class SecondClass:
name: str
code: 'str | None' = field(init=False)
def __post_init__(self, ):
object.__setattr__(self, 'code', self.name.lower())
print(SecondClass('Test'))
Another option could be to add a helper class method new()
which can be used to instantiate a new SecondClass
object:另一种选择可能是添加一个帮助器 class 方法
new()
可用于实例化新的SecondClass
object:
from dataclasses import dataclass
@dataclass(frozen=True)
class SecondClass:
name: str
code: 'str | None'
@classmethod
def new(cls, name: str):
return cls(name, name.lower())
print(SecondClass.new('Hello'))
Another approach, using @property
- doesn't store code
in the class but exposes it as an attribute:另一种方法,使用
@property
- 不在 class 中存储code
,而是将其作为属性公开:
@dataclass(frozen=True)
class SecondClass:
name: str
@property
def code(self):
return self.name.lower()
print(SecondClass('Me').code)
Result:结果:
me
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.