python的类属性与实例属性——继承与java或php的差异

写java、php写多了,以为python的类跟他们是一样的,结果今天遇到一个类属性的诡异现象,跟完发现在类属性上,python有个很特殊的地方,就是在子类调用父类的方法修改父类属性时,会影响到同进程的其它子类实例。例子如下:

class TestBase:
 test={}
def __init__(self, key):
self.test[key] = 1
def get(self):
return self.test

class TestA(TestBase):
def get(self):
return self.test

class TestB(TestBase):
def get(self):
return self.test

key = ‘aaa’
tb = TestA(key)
print tb.get()

key = ‘bbb’
tb = TestB(key)
print tb.get()

我想当然的认为输出结果会是:

{‘aaa’: 1}
{‘bbb’: 1}

没想到实际输出的是:
{‘aaa’: 1}
{‘aaa’: 1, ‘bbb’: 1}

也就是说,两个不同的子类的不同实例之间,类的属性竟然是打通的。。。查了一下后发现python的逻辑是这样的:在定义类属性的位置声明的属性是类属性改变它的值会影响所有继承它的类实例;如果不声明直接在函数中使用self.xxx的属性,是实例属性,生命周期只存在于当前实例中,对当前实例外没有任何影响。

也就是上边的badcase解决方法是:

class TestBase:
def __init__(self, key):
self.test={}
self.test[key] = 1
def get(self):
return self.test

class TestA(TestBase):
def get(self):
return self.test

class TestB(TestBase):
def get(self):
return self.test

key = ‘aaa’
tb = TestA(key)
print tb.get()

key = ‘bbb’
tb = TestB(key)
print tb.get()

 

输出结果:

{‘aaa’: 1}
{‘bbb’: 1}

发表评论

电子邮件地址不会被公开。