为什么即使在创建了一个新的类实例后我仍然保持不变?
class Test(object):
i = 0
def add(self):
Test.i += 1
运行此代码
t = Test()
print t.i
t.add()
t2 = Test()
print t2.i
print t.i
给出
0
1
1
为什么t.i和t2.i都不等于0?它们不应该等于0,因为行t2 = Test()
会将i重置为0吗?
答案 0 :(得分:2)
i
是一个类变量,而不是实例变量。它与类本身绑定(这就是为什么你可以编写Test.i
,即使没有Test
的实例存在)。
您必须使i
成为实例变量:
class Test(object):
def __init__(self):
self.i = 0
def add(self):
self.i += 1
答案 1 :(得分:1)
您正在修改整个类的属性,而不是实例的属性。试试这个:
class Test(object):
i = 0
def add(self):
self.i += 1
Python会自动将实例作为参数self
传递给方法。因此,在方法中,您可以将实例的属性称为self.i
。
答案 2 :(得分:0)
class Test(object):
i = 0
def add(self):
Test.i += 1
print "Test.i == ",Test.i
print "'i' in dir(Test) == ",'i' in dir(Test)
print "'i' in Test.__dict__ == ",'i' in Test.__dict__
t1 = Test()
print '\n# t1 = Test() executed'
print "t1.i == ",t1.i
print "'i' in dir(t1) == ",'i' in dir(t1)
print "'i' in t1.__dict__ == ",'i' in t1.__dict__
结果
Test.i == 0
'i' in dir(Test) == True
'i' in Test.__dict__ == True
# t1 = Test() executed
t1.i == 0
'i' in dir(t1) == True
'i' in t1.__dict__ == False
对象的名称__dict__
的属性是表示此对象的名称空间的字典,也就是说它包含对象的属性。
另外,我们有:
DIR([对象])
如果对象具有名为
__dir__()
的方法,则将调用此方法 并且必须返回属性列表。
那么,dir(t1)
如何包含属性 i 而t1.__dict__
不包含?
所有两个dir(Test)
和Test.__dict__
都包含属性 i ?
这与您回答问题的原因相同:
返回对象属性的行为很尴尬
`dir(object)
反映了这种尴尬:
默认的dir()机制对不同类型的行为有所不同 对象,因为它试图产生最相关的,而不是 完整,信息:
•如果对象是模块对象,则列表包含的名称 模块的属性。
•如果对象是类型或类对象,则 list包含其属性的名称,以及递归的 其基础的属性 •否则,列表包含对象的 属性'名称,其类属性的名称,和 递归地类的基类的属性。
然后,您的问题的答案分为两部分:
1)dir(t1)
给出被认为是对象的属性,但对象的真实NAMESPACE,公开为t1.__dict__
不包含属性 i ,事实上,正如已经回答的那样,这是一个阶级的属性。
因此,两个实例 t1 和 t2 的伪属性 i 显示为等于,因为表达式t1.i
和{{1事实上,评估为t2.i
,
与Test.i
和dir(t1)
包含类的属性dir(t2)
的方式相同
2)表达式Test.i
如何评估为t1.i
??
因此(构成我答案的附加信息):
一个类实例有一个名称实现为字典的名称空间 搜索属性引用的第一个位置。当一个 在那里找不到属性,并且实例的类有一个 通过该名称的属性,搜索继续该类 属性。
http://docs.python.org/reference/datamodel.html#the-standard-type-hierarchy
这意味着当在对象的命名空间中找不到属性时,会在对象是实例的类的命名空间中搜索它。