如何在 Python 中的 Dataclasses 中使用 __post_init__ 方法 [英] How to use the __post_init__ method in Dataclasses in Python
问题描述
我正在尝试使用 Python 中的数据类来弄脏我的手,我想做的是在我的类中有一个计算字段,并将 sort_index 字段添加到调用中,但也想让它冻结,这样我就不能定义后修改该类的任何属性.下面是我的代码:
I am trying to get my hands dirty with dataclasses in Python and what i want to do is have a computed field inside my class and also add the sort_index field to the call but would also want to make it frozen so that i cannot modify any attributes of this class after definition. Below is my code:
from dataclasses import dataclass, field
def _get_year_of_birth(age: int, current_year: int=2019):
return current_year - age
@dataclass(order=True, frozen=True)
class Person():
sort_index: int = field(init=False, repr=False)
name: str
lastname: str
age: int
birthyear: int = field(init=False)
def __post_init__(self):
self.sort_index = self.age
self.birthyear = _get_year_of_birth(self.age)
if __name__ == "__main__":
persons = [
Person(name="Jack", lastname="Ryan", age=35),
Person(name="Jason", lastname="Bourne", age=45),
Person(name="James", lastname="Bond", age=60)
]
sorted_persons = sorted(persons)
for person in sorted_persons:
print(f"{person.name} and {person.age} and year of birth is : {person.birthyear}")
似乎我无法在我的班级中设置自定义排序字段,也无法创建任何从其他属性计算的属性,因为我使用了 freeze .当我运行上面的我得到以下错误:
It seems that i cannot set a custom sort field inside my class and also cannot create any attribute which is computed from other attributes since i am using frozen . When i run the above i get the below error:
Traceback (most recent call last):
File "dataclasses_2.py", line 30, in <module>
Person(name="Jack", lastname="Ryan", age=35),
File "<string>", line 5, in __init__
File "dataclasses_2.py", line 23, in __post_init__
self.sort_index = self.age
File "<string>", line 3, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'sort_index'
有没有更好的方法来做到这一点?请帮忙
Is there a better way of doing this ? Please help
推荐答案
问题是您正在尝试设置冻结对象的字段.这里有两个选项.第一个选项是从数据类规范中删除 frozen=True
.其次,如果您仍然想冻结 Person 实例,那么您应该使用方法 __set_atr__
初始化字段.因此,您的 post_init 方法将变为:
The problem is you are trying to set a field of a frozen object.
There are two options here. First option would be to remove frozen=True
from the dataclass specification. Secondly, if you still want to freeze Person instances, then you should initialize fields with method __set_atr__
. Therefore, your post_init method will become:
def __post_init__(self):
object.__setattr__(self, 'sort_index', self.age)
object.__setattr__(self, 'birthyear', _get_year_of_birth(self.age)
这篇关于如何在 Python 中的 Dataclasses 中使用 __post_init__ 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!