两个 python 类 如何声明彼此和自身的引用?

How can two python classes declare references each other and itself?

这是一个非常基础的问题,实际上是两个问题合二为一。暴露我的 Python 绿色的希望非常简单的答案对于这两个问题可能是相同的。

下面的代码有两个问题:

    #! /usr/bin/python3.10
    
    class A:
       a:A=A()
       b:B=B()
    
    class B:
       a:A=A()
       b:B=B()

我有类型错误,想使用 mypy。如果我在 class 声明之外创建变量作为属性或以其他方式隐藏所需的类型,则 mypy 将看不到类型声明并且无法解析我的程序以查找类型错误。

你可能会问我为什么要这个?递归数据结构有不定式的应用,但是...

能否Python以 mypy 可以满足类型声明的方式做这些非常基本的事情?

我开始认为 'python way' 是为每个函数对每个参数进行类型检查。我越想越觉得解释型语言提出这样的要求是合乎逻辑的,但我还是希望我的代码尽可能保持井井有条和声明式。

我认为您的部分问题没有解决方案。您的声明:

class A:
   a:A=A()
   b:B=B()

表示 A().a 是 A 的另一个实例,A 又引用另一个 A,依此类推。这不一定是个问题,但如果它成为对象创建或实例化的一部分,将自动需要无限数量的对象!也许你可以这样做:

from typing import Optional


class A:
    a: Optional["A"]
    def __init__(self, other: Optional["A"] = None):
        self.a = other

这将允许您有一个基本情况(self.a 是 None)和其他情况,其中 self.a 是 A 的另一个实例。

注意上面也用“A”来定义类型。这让你解决了类型提示问题,虽然我不知道它如何与 mypy 一起玩!您可以应用它,以便您的解决方案看起来像:

from typing import Optional


class A:
    a: Optional["A"]
    b: Optional["B"]

class B:
    a: Optional["A"]
    b: Optional["B"]

[根据评论中的讨论编辑答案。]

如果您想要使用 __init__ 方法的递归 class 定义,那么正确的实现将取决于您的目标,但 可能是您想要的。但是,如果你真的需要静态 class 成员,你可以在声明两个 classes:

之后初始化它们
class A:
    a: 'A'
    b: 'B'

class B:
    a: 'A'
    b: 'B'

A.a = A()
A.b = B()
B.a = A()
B.b = B()