如何在Python 3.7+中定义循环相关的数据类?

Nae*_*mul 14 python circular-dependency python-3.x python-dataclasses

假设class A有一个类型为的成员class B,并且class B有一个类型为的成员class A.

在Scala或Kotlin中,您可以按任何顺序定义类,而不必担心在这种情况下,因为第一个定义的类可以像往常一样使用第二个定义的类,即使在case/data类中也是如此.

但是在Python中,以下代码

class A:
    b = B()

class B:
    a = A()     
Run Code Online (Sandbox Code Playgroud)

抛出编译错误,因为class B在定义时class A未定义.

你可以解决这个简单的案例,就像在这个答案中一样

class A:
    pass

class B:
    a = A()

A.b = B()
Run Code Online (Sandbox Code Playgroud)

但是,这种方式对Python中的数据类不起作用,因为在定义数据类之后分配成员不会更新数据类的自动生成方法,这使得"数据类"的使用变得无用.

@dataclass
class A:
    b: B  # or `b: Optional[B]`

@dataclass
class B:
    a: A  # or `a: Optional[A]`
Run Code Online (Sandbox Code Playgroud)

我该如何避免这个问题?

Aco*_*orn 11

有几种方法可以解决这种循环依赖关系,请参阅类型提示:解决循环依赖关系

您可以随时手动应用装饰器(并更新注释),如@Neceoo的答案节目.

但是,"转发声明"类可能更容易:

class A:
    pass

@dataclass
class B:
    a: A

@dataclass
class A:
    b: B
Run Code Online (Sandbox Code Playgroud)

或者只是使用前向参考:

@dataclass
class B:
    a: 'A'

@dataclass
class A:
    b: B
Run Code Online (Sandbox Code Playgroud)

最干净的是导入Python 4.0的行为(如果可以的话):

from __future__ import annotations

@dataclass
class B:
    a: A

@dataclass
class A:
    b: B
Run Code Online (Sandbox Code Playgroud)

  • 实际上,看起来前向声明在这种情况下也不起作用...... (2认同)