我试图将一个变量添加到一个保存类的实例的类中。以下是我的代码的缩短版本。
class Classy :
def __init__(self) :
self.hi = "HI!"
# "CLASSIES" variable holds instances of class "Classy"
CLASSIES = []
for i in xrange(0,4) :
CLASSIES.append(Classy())
运行代码后,我收到以下错误。
Traceback (most recent call last):
File "classy.py", line 6, in Classy
CLASSIES.append(Classy())
NameError: name 'Classy' is not defined
是否有另一种方法可以将类的实例添加到该类中的类/静态变量中?
答案 0 :(得分:3)
在创建类之前执行类主体。因此,您尝试在类存在之前实例化该类。您仍然可以将实例附加到类,但您必须在类主体完成后创建它们,例如:
class Classy(object):
def __init__(self):
self.hi = "HI!"
CLASSIES = []
for i in xrange(4):
Classy.CLASSIES.append(Classy())
但是,我建议你首先想一想你是否真的需要这个有效的全局列表,以及你是否需要它成为类对象的一部分。就个人而言,我几乎从未做过这样的事情。
答案 1 :(得分:2)
最简单的方法是在创建类之后,定义类时执行此操作,因此可以使用:
class Classy :
CLASSIES = []
def __init__(self) :
self.hi = "HI!"
Classy.CLASSIES = [Classy() for _ in xrange(0,4)]
(这里使用list comprehension方便,因为这是构建列表最可读和最有效的方法。)
另请注意,如果这是一个常量,你应该把它变成一个元组而不是一个列表,如果它不是,你可能不应该使用ALL_CAPS
这个名字,按惯例,暗示一个常数。
答案 2 :(得分:2)
在我看来,你想要获得:
class Classy :
CLASSIES = []
def __init__(self) :
self.hi = "HI!"
Classy.CLASSIES.append(self)
for i in xrange(4):
Classy()
for x in Classy.CLASSIES:
print x
结果
<__main__.Classy instance at 0x011DF3F0>
<__main__.Classy instance at 0x011DF440>
<__main__.Classy instance at 0x011DF418>
<__main__.Classy instance at 0x011DF2B0>
请注意使用Lattyware的代码:
class Classy :
CLASSIES = []
idC = id(CLASSIES)
def __init__(self) :
self.hi = "HI!"
#Classy.CLASSIES.append(self)
Classy.CLASSIES = [Classy() for _ in xrange(0,4)]
print Classy.idC
print id(Classy.CLASSIES)
print 'Classy.idC==id(Classy.CLASSIES) :',Classy.idC==id(Classy.CLASSIES)
结果
18713576
10755928
Classy.idC==id(Classy.CLASSIES) : False
使用denan'代码的for循环时,它不会出现。
但是很容易纠正:
写作
Classy.CLASSIES[:] = [Classy() for _ in xrange(0,4)]
或
Classy.CLASSIES.extend(Classy() for _ in xrange(0,4))
而不是
Classy.CLASSIES = [Classy() for _ in xrange(0,4)]
这取决于你想要什么。
方法可以像普通方式一样引用全局名称 功能。与方法关联的全局范围是模块 包含其定义。 (一个类永远不会被用作全局范围。)
http://docs.python.org/2/tutorial/classes.html#class-definition-syntax
类具有由字典对象实现的命名空间。类 属性引用被转换为此字典中的查找, 例如,
C.x
被翻译为C.__dict__["x"]
http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes
class Classy :
CLASSIES = []
print '"CLASSIES" in globals()',"CLASSIES" in globals()
print '"CLASSIES" in Classy.__dict__ ==',"CLASSIES" in Classy.__dict__
结果
"CLASSIES" in globals() False
"CLASSIES" in Classy.__dict__ == True
德尔南,你将如何继续假装CLASSIES是全球性的?
我在与Lattyware的辩论中误解了什么吗?
答案 3 :(得分:1)
在类块完成执行之后才会定义类本身,因此您无法在其自己的定义中使用该类。
在创建类之后,您可以使用类装饰器或元类来添加所需的类变量。这是一个装饰器的例子。
def addClassy(cls):
cls.CLASSIES = [cls() for a in xrange(4)]
return cls
@addClassy
class Classy(object):
pass
>>> Classy.CLASSIES
0: [<__main__.Classy object at 0x000000000289A240>,
<__main__.Classy object at 0x000000000289A518>,
<__main__.Classy object at 0x000000000289A198>,
<__main__.Classy object at 0x000000000289A208>]