簡體   English   中英

Python:數據類的循環依賴/前向變量聲明?

[英]Python: Circular dependency of dataclasses / Forward variable declaration?

所以,我在一個文件中有這兩個數據類:

@dataclass
class A:
    children: List[B]

@dataclass
class B:
    parent: A

,這可以通過使用__future__.annotations特性來實現。

然后我有另外兩個文件,每個文件都有一堆針對我的項目的每種類型的對象,這些對象是 static。

文件objects_A

import objects_B

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

文件objects_B

import objects_A

obj_b1 = B(
    parent=objects_A.obj_a1
)

obj_b2 = B(
    parent=objects_A.obj_a1
)

顯然,文件之間存在循環依賴問題,但即使它們在同一個文件中也不行,因為一種類型的變量依賴於另一種類型的變量才能成功。
初始化obj_a1中的B對象也不起作用,因為這里沒有self的概念。

目前,我將parent設置為None (反對類型提示),然后在obj_a1上循環以設置它們:

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

伙計們有什么好主意嗎?
不知道它是否有幫助,但這些對象是 static(它們在這些聲明后不會改變)並且它們具有某種父子關系(正如您肯定已經注意到的那樣)。
如果可能的話,我希望將每種類型的變量放在不同的文件中。

我知道我遲到了,但我會在這里留下我的答案供其他人使用。

根據PEP 563 ,python 3.7 引入了注釋的惰性求值,這在循環依賴的情況下非常有用。

@dataclass
class StudentData:
    school: 'SchoolData'

@dataclass
class SchoolData:
    students: StudentData

如您所見, SchoolData類型注釋包含在引號內,這樣您就可以在聲明之前引用SchoolData類型。

解決此問題的一種方法是使用基礎 class 作為前向聲明的替代方案。

@dataclass
class ParentBase:
    children: List[object]


@dataclass
class Child:
    parent: ParentBase


@dataclass
class Parent(ParentBase):
    children: List[Child]



parent = Parent(children=[])
child = Child(parent=parent)
parent.children.append(child)

這將起作用。 我在ParentBase添加了children: List[object] 這不是此代碼工作所必需的,但如果您添加它,您的 IDE 可以在您開始訪問child.parent. .

不會阻止任何人使用ParentBase實例化Child 要解決該問題,您可以執行以下操作:

@dataclass
class ParentBase(abc.ABC):
    children: List[object]

    @abc.abstractmethod
    def __post_init__(self):
        pass


@dataclass
class Child:
    parent: ParentBase


@dataclass
class Parent(ParentBase):
    children: List[Child]

    def __post_init__(self):
        pass


parent = Parent(children=[])
child = Child(parent=ParentBase())  # TypeError
child = Child(parent=parent)
parent.children.append(child)

它可能過於防御和過多的樣板代碼。 是否要使其更安全取決於您團隊的偏好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM