Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Circular dependency of dataclasses / Forward variable declaration?

So, I have these two dataclasses in a file:

@dataclass
class A:
    children: List[B]

@dataclass
class B:
    parent: A

, which are possible with the use of the __future__.annotations feature.

Then I have two other files, each with a bunch of objects for each type that are static for my project.

File objects_A:

import objects_B

obj_a1 = A(
    children=[
        objects_B.obj_b1,
        objects_B.obj_b2
    ]
)

File objects_B:

import objects_A

obj_b1 = B(
    parent=objects_A.obj_a1
)

obj_b2 = B(
    parent=objects_A.obj_a1
)

Obviously, there a circular dependency problem between the files, but it wouldn't work even if they were in the same file, as a variable of one type depends on the other to succeed.
Initialising the B objects inside obj_a1 also won't work as there is no concept of self here.

At the moment, I'm setting parent to None (against the type hinting), and then do a loop on obj_a1 to set them up:

for obj_b in obj_a1.children:
    obj_b.parent = obj_a1

Any bright ideas folks?
Don't know if it helps, but these objects are static (they will not change after these declarations) and they have kind of a parent-children relationship (as you surely have noticed).
If possible, I would like to have the variables of each type in different files.

like image 996
gmardau Avatar asked Aug 05 '26 04:08

gmardau


1 Answers

I know that I'm late but I'll just leave my answer here for others to use.

According to PEP 563, python 3.7 has introduced lazy evaluation of annotations which can be very useful in the case of a circular dependency.

@dataclass
class StudentData:
    school: 'SchoolData'

@dataclass
class SchoolData:
    students: StudentData

As you can see, the SchoolData type annotation is wrapped inside quotations which allows you to reference the SchoolData type before its declaration.

like image 154
A.Mohammadi Avatar answered Aug 07 '26 17:08

A.Mohammadi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!