在类定义中实例化类
我正在尝试给一个类添加一个变量,这个变量用来保存这个类的实例。下面是我代码的简化版本。
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
有没有其他方法可以在这个类里面,把类的实例添加到一个类变量或者静态变量中呢?
4 个回答
最简单的方法是在类创建之后,也就是类定义好之后再进行操作,这样就可以使用这个类了:
class Classy :
CLASSIES = []
def __init__(self) :
self.hi = "HI!"
Classy.CLASSIES = [Classy() for _ in xrange(0,4)]
(这里使用了列表推导式,因为它是构建列表最清晰和高效的方法)。
另外,如果你打算把这个当作常量使用,最好把它做成一个元组,而不是列表。如果不是常量,建议不要用ALL_CAPS
这种命名方式,因为按照惯例,这种命名方式通常表示常量。
看起来你想要得到这个:
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
而使用delnan的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)]
这要看你想要什么结果。
编辑 2
方法可以像普通函数一样引用全局变量。与方法相关的全局范围是包含其定义的模块。(类本身不会作为全局范围使用。)
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
Delnan,你怎么还会继续假装CLASSIES是全局的呢??
我是不是在你和Lattyware的讨论中理解错了什么?
类的主体在类被创建之前就会执行。因此,你是在类还不存在的时候就试图去实例化它。虽然你可以把实例附加到类上,但你必须在类的主体执行完之后再去创建它们,比如:
class Classy(object):
def __init__(self):
self.hi = "HI!"
CLASSIES = []
for i in xrange(4):
Classy.CLASSIES.append(Classy())
不过,我建议你先认真考虑一下,自己是否真的需要这个几乎是全局的列表,以及是否需要把它作为类的一部分。就我个人而言,我几乎从来不这样做。