我有一个文件中的一系列Python类的。有些类引用他人。
我的代码是这样的:
class A():
pass
class B():
c = C()
class C():
pass
尝试运行,我得到NameError: name 'C' is not defined
。不够公平,但有什么办法,使其工作,或者我需要手动重新整理我的课,以适应?在C ++中,我可以创建一个类的原型。 Python中是否有相同呢?
(实际上,我与Django模型玩,但我想不是使问题复杂化)。
在Python你不创建一个原型本身,而是你需要理解之间的“类属性”和实例级属性的差异。在您在上面示出的示例中,将声明类B,不是一个实例级属性上的类属性。
这是你在找什么:
class B():
def __init__(self):
self.c = C()
事实上,上述所有的都是关于Python伟大的意见,但没有人会解决你的问题。
Django的需要反思的东西。
做你想做什么是正确的方法如下:
class Car(models.Model):
manufacturer = models.ForeignKey('Manufacturer')
# ...
class Manufacturer(models.Model):
# ...
注意,这里使用的类名作为一个字符串,而不是字面类引用。 Django还提供了这种替代对付正是Python没有提供前置声明的问题。
这个问题让我想起了经典的支持问题,你应该总是要求客户有一个问题:“什么是你真正想要做的”
为呈现这将解决你的问题(但我认为你真正需要的实例属性为jholloway7回应):
class A:
pass
class B:
pass
class C:
pass
B.c = C()
Python没有原型或者Ruby式的公开课。但是,如果你真的需要它们,你可以写一个重载新,因此,它并看到在当前命名空间中查找,如果已经存在于类元类,如果它返回现有类型的对象,而不是创建一个新的。我做了这样的事情在一个ORM我写了一段时间后,它的工作非常出色。
有关类VS实例属性所有正确的答案。但是,你有一个错误的原因是定义你的类的只是顺序。当然C类尚未定义(作为类级别代码被立即执行的上进口):
class A():
pass
class C():
pass
class B():
c = C()
将工作。
这个问题十年后是问,我也遇到了同样的问题。虽然人们建议,应该参考init方法里面做,有些时候你需要访问数据为“类属性”上课之前实际实例。出于这个原因,我想出了用描述一个简单的解决方案。
class A():
pass
class B():
class D(object):
def __init__(self):
self.c = None
def __get__(self, instance, owner):
if not self.c:
self.c = C()
return self.c
c = D()
class C():
pass
>>> B.c
>>> <__main__.C object at 0x10cc385f8>