彼此引用的python类

Dan*_*iel 8 python oop django

我有两个相互引用的类,但显然编译器抱怨.有没有办法解决?

编辑

实际上我的代码与Hank Gay使用的代码略有不同.因此python绝对可以处理某些循环引用,但在以下情况下会抛出错误.下面是我得到的,我得到一个'名称Y未定义错误'

class X(models.Model):

        creator = Registry()
        creator.register(Y)

class Y(models.Model):
    a = models.ForeignKey(X)
    b = models.CharField(max_length=200)
Run Code Online (Sandbox Code Playgroud)

希望这有助于澄清.有什么建议.

Jon*_*ker 17

在python中,类的代码在加载类时运行.

现在,到底是什么意思?;-)

请考虑以下代码:

class x:
    print "hello"
    def __init__(self): print "hello again"
Run Code Online (Sandbox Code Playgroud)

当您加载包含代码的模块时,python将打印hello.每当你创建一个x,python将打印hello again.

你可以认为def __init__(self): ...是等价的__init__ = lambda self: ...,除了python lambda限制都没有适用.也就是说,这是def一个赋值,它可以解释为什么运行外部方法而不是内部方法的代码.

当你的代码说

class X(models.Model):
    creator = Registry()
    creator.register(Y)
Run Code Online (Sandbox Code Playgroud)

您可以参考Y加载模块的时间,之前Y有值.您可以将其class X视为一个赋值(但我不记得创建匿名类的语法;也许它是一个调用type?)

您可能想要做的是:

class X(models.Model):
    pass
class Y(models.Model):
    foo = something_that_uses_(X)
X.bar = something_which_uses(Y)
Run Code Online (Sandbox Code Playgroud)

也就是说,创建创建后X引用的类属性.或者反之亦然:创建第一个,然后,然后的属性,这取决于,如果这是更容易.YYYXYX

希望这可以帮助 :)


fok*_*oki 5

这是一个很好的问题。虽然其他人已经回答了,但我会随意提供另一个例子。

考虑这个程序。

@dataclass
class A:
    b: B

class B:
    def __init__(self):
        pass
Run Code Online (Sandbox Code Playgroud)

b现在是一个级变量,这个程序不起作用。当 Python 解释器加载(执行) class 的代码时,该名称B尚未定义A。与编译语言(例如 C/C++)不同,解释器从文件的开头到结尾逐个命令地执行代码,一次完成。由于Python需要知道B它定义类时是什么A,所以它失败了。B稍后才定义。

现在,考虑一个稍微不同的程序。

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

class B:
    def __init__(self):
        pass
Run Code Online (Sandbox Code Playgroud)

b现在是一个对象级变量并且该程序可以运行。Python 仍然在单遍中从文件的开头到结尾执行代码,但是,现在它不需要知道B读取该行时的内容self.b = B()。这是因为__init__只有当有人想要构造 class 的对象时才会执行该方法A。由于对象的构造将在程序稍后的某个位置发生(当B已经定义时),__init__因此在需要时可以正常工作。