写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}