【问题标题】:Dataclass: How do I create a field that does not need initializing which is automatically generated?Dataclass:如何创建一个不需要初始化的自动生成的字段?
【发布时间】:2020-08-26 19:37:08
【问题描述】:

我使用 field(init= False) 来禁用初始化 self.ref。然后它是post中的一个值。以下代码引发AttributeError: 'Data' object has no attribute 'ref'

from dataclasses import dataclass, field
def make_list(): return [[0] for k in range(9)]
@dataclass
class Data:
    rows: list
    cols: list
    blocks: list
    ref: dict = field(init=False)

    def __init__(self, slots=None):
        self.rows = make_list()
        self.cols = make_list()
        self.blocks = make_list()
        if slots:
            for i in range(9):
                for j in range(9):
                    self.cols[j][i] = self.rows[i][j] = slots[i][j]

    def __post_init__(self):  
          print("post-init executed")
        self.ref = {"rows": self.rows, "cols": self.cols, "blocks": self.blocks}
test = Data()
print(test)

我正在使用 python 3.8。该代码在 pycharm/jupyter 中都经过测试。 (同样的错误)

编辑:更正错字后:__post__init__ to __post_init__,我仍然收到错误。

【问题讨论】:

  • 非常正确。感谢您发现它。
  • 我进行了更正,但仍然遇到同样的错误。 post 中的 print-statement 仍未执行。
  • 嗯,但你从来没有叫过它。通常自动生成的__init__ 调用 post init 钩子,但既然你自己写了__init__,现在就看你自己了..
  • 老实说,如果您要编写__init__,为什么还要创建一个数据类?它不接受任何与属性相对应的参数?
  • @wim 好的,我想我明白了。如果__init__ 不是自动生成的,__post__init__ 是多余的。并且没有被调用。那么,所有进程都在 init 中吗?删除__post_init__?

标签: python python-3.x python-dataclasses


【解决方案1】:

感谢@wim 和@juanpa.arrivillaga

删除__init__ 将解决问题并让__post_init__ 再次运行。 (正如wimjuanpa.arrivillaga 所指出的)如果我自己写__init__,为什么还要写__post_init__,我可以在那里写所有我想要的所有后处理。 (线序)

from dataclasses import dataclass, field

@dataclass
class Data:
    rows: list
    cols: list = field(init=False) 
    blocks: list = field(init=False)
    ref: dict = field(init=False)

    def __post_init__(self): 
        print("post init\n\n")
        self.cols = [k*10 for k in self.rows]  # code transform rows to cols
        self.blocks = [k*20 for k in self.rows]  # code transform rows to blocks
        self.ref = {"rows": self.rows, "cols": self.cols, "blocks": self.blocks}

test = Data([1,2,3])
print(test)

另外,我可能想重新考虑使用常规类重写它,因为这里使用的数据类只提供常规类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 2011-12-07
    • 2019-09-17
    相关资源
    最近更新 更多