我有两个相互引用的类,但显然编译器抱怨.有没有办法解决?
编辑
实际上我的代码与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
引用的类属性.或者反之亦然:创建第一个,然后,然后的属性,这取决于,如果这是更容易.Y
Y
Y
X
Y
X
希望这可以帮助 :)
这是一个很好的问题。虽然其他人已经回答了,但我会随意提供另一个例子。
考虑这个程序。
@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__
因此在需要时可以正常工作。
归档时间: |
|
查看次数: |
11630 次 |
最近记录: |