从另一个嵌套数据类访问一个嵌套类

时间:2019-10-02 04:24:30

标签: python python-3.7 inner-classes data-class

现在以下代码可完美地与Python 3.7配合使用

class A:
    class B:
        def __init__(self):
            print("B")

    class C:
        def __init__(self):
            self.b = A.B()

def main():
    a = A.C()

if __name__ == "__main__":
    main()

它将在屏幕上打印B

但是,如果尝试进行小的修改以引入数据类,则代码将无法正常运行。

from dataclasses import dataclass

class A:
    class B:
        def __init__(self):
            print("B")

    @dataclass
    class C:
        b = A.B()

def main():
    a = A.C()

if __name__ == "__main__":
    main()

Python报告-适用于b = A.B()-NameError: name 'A' is not defined

有人知道如何解决此问题以实现与数据类相同的结果吗?为什么说name 'A' is not defined

2 个答案:

答案 0 :(得分:2)

直到到达class语句的正文末尾才创建类对象,这就是为什么在定义类A时不能对其进行引用的原因。另一方面,在A方法内引用__init__是有效的,因为在调用A方法时已经定义了类__init__

您可以改为使用typing.TypeVarA.B定义前向引用类型b,并为其分配默认值field和{{1 }}函数在调用时返回default_factory的实例:

A.B

这将输出:

from dataclasses import dataclass, field
from typing import TypeVar

class A:
    class B:
        def __init__(self):
            print("B")

    @dataclass
    class C:
        b: TypeVar('A.B') = field(default_factory=lambda: A.B())

def main():
    a = A.C()

if __name__ == "__main__":
    main()

答案 1 :(得分:0)

另一种推迟初始化的方法,直到定义class A并可用,而无需触摸生成的__init__

@dataclass
class C:
    b: TypeVar('A.B') = field(init=False)

def __post_init__(self):
    self.b = A.B()

请参阅official docs