【问题标题】:How to use the __post_init__ method in Dataclasses in Python如何在 Python 的 Dataclasses 中使用 __post_init__ 方法
【发布时间】:2020-03-31 23:24:37
【问题描述】:

我正在尝试用 Python 中的数据类弄脏我的手,我想做的是在我的类中有一个计算字段,并将 sort_index 字段添加到调用中,但也想让它冻结,这样我就不能定义后修改此类的任何属性。以下是我的代码:

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 。当我运行上面我得到以下错误:

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'

有没有更好的方法呢?请帮忙

【问题讨论】:

标签: python-3.7 python-dataclasses


【解决方案1】:

问题是您正在尝试设置冻结对象的字段。 这里有两个选项。第一个选择是从数据类规范中删除frozen=True。其次,如果您仍想冻结 Person 实例,则应使用方法 __set_atr__ 初始化字段。因此,您的 post_init 方法将变为:

def __post_init__(self):
    object.__setattr__(self, 'sort_index', self.age)
    object.__setattr__(self, 'birthyear', _get_year_of_birth(self.age)

【讨论】:

  • 这个答案不正确。 self.__setattr__ 正是引起FrozenInstanceError 的原因。您想要的是object.__setattr__(self, ...),如上面已经提到的答案中所述:stackoverflow.com/a/54119384/8960865
  • 感谢指出错误,现已修复。
猜你喜欢
  • 1970-01-01
  • 2020-07-30
  • 2019-02-28
  • 1970-01-01
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多