如何在 Python 中的 Dataclasses 中使用 __post_init__ 方法 [英] How to use the __post_init__ method in Dataclasses in Python

查看:322
本文介绍了如何在 Python 中的 Dataclasses 中使用 __post_init__ 方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆