I used field(init= False) to disable initializing self.ref. It is then a value in post. The following code raises 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)
I am using python 3.8. The code is tested in both pycharm/jupyter. (Same error)
Edit: after correcting the typo: __post__init__ to __post_init__ , I am still getting the error.
Thanks to @wim and @juanpa.arrivillaga
Deleting the __init__ would fix the problem and let the __post_init__ run again.
(As pointed out by wim and juanpa.arrivillaga) If I write my own __init__ , why even bother writing __post_init__ , I can write all post processing all I want in there. (line order)
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)
Also, I might want to reconsider rewriting it using regular class as the code stands now since using dataclass here does not provide anything more than a regular class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With