Python 父类、子类的数据掺杂到一起了?
2012-12-08 12:16
309 查看
以此为例:
class A:
attr_list = []
def __init__(self, attr_list = []):
self.attr_list = attr_list
def __del__(self):
del self.attr_list[:]
def addAttr(self, attr):
self.attr_list.append(attr)
class B(A):
def __init__(self):
pass
class C(A):
def __init__(self):
pass
b = B()
c = C()
b.addAttr(1)
c.addAttr(2)
for attr in b.attr_list:
print attr ## 此处输出1,2
for attr in c.attr_list:
print attr ## 此处也输出1,2
奇怪了,从基类A派生出两个不同的子类B、C,分别定义了一个实例b、c并各自添加数据1、2,怎么会导致两个实例中的数据都是1,2呢?难道他们用的是一个地址?好说,来,来验证一下!
print id(b.attr_list)
print id(c.attr_list)
打印出来的两个地址果然是一样的,原来如此!那为什么会这样呢?
仔细看,才发现原因出在A中attr_list定义的位置不对,对python而言,在类名和__init__之前定义的变量(注意,这时候是不能用self的,因为不识别),是类全局的, 可以认为和C++类中的静态变量等价,这样就可以解释了。
那究竟应该怎么定义类的普通变量呢?简单,在__init__函数中,使用self来定义就OK了,改造如下:
class A: ##不要在此处和__init__之间定义普通变量,除非你真的想用它做静态变量,否则。。。
def __init__(self, attr_list = []):
self.attr_list = attr_list
而且还有一个注意点,子类B、C的__init__函数中,首行就应该先调用父类A的__init__函数,__del__如是。
改造如下:
class A:
def __init__(self, attr_list = []):
self.attr_list = attr_list
def __del__(self):
del self.attr_list[:]
def addAttr(self, attr):
self.attr_list.append(attr)
class B(A):
def __init__(self):
A.__init__(self)
class C(A):
def __init__(self):
A.__init__(self)
再次分别声明变量b、c并添加1、2,打印出来看看,哈哈,果然分开了,分别是1、2.
看来还是自己对python的机制理解不够,导致出现这种使用问题,不过吃一堑长一智,还是很幸运。
class A:
attr_list = []
def __init__(self, attr_list = []):
self.attr_list = attr_list
def __del__(self):
del self.attr_list[:]
def addAttr(self, attr):
self.attr_list.append(attr)
class B(A):
def __init__(self):
pass
class C(A):
def __init__(self):
pass
b = B()
c = C()
b.addAttr(1)
c.addAttr(2)
for attr in b.attr_list:
print attr ## 此处输出1,2
for attr in c.attr_list:
print attr ## 此处也输出1,2
奇怪了,从基类A派生出两个不同的子类B、C,分别定义了一个实例b、c并各自添加数据1、2,怎么会导致两个实例中的数据都是1,2呢?难道他们用的是一个地址?好说,来,来验证一下!
print id(b.attr_list)
print id(c.attr_list)
打印出来的两个地址果然是一样的,原来如此!那为什么会这样呢?
仔细看,才发现原因出在A中attr_list定义的位置不对,对python而言,在类名和__init__之前定义的变量(注意,这时候是不能用self的,因为不识别),是类全局的, 可以认为和C++类中的静态变量等价,这样就可以解释了。
那究竟应该怎么定义类的普通变量呢?简单,在__init__函数中,使用self来定义就OK了,改造如下:
class A: ##不要在此处和__init__之间定义普通变量,除非你真的想用它做静态变量,否则。。。
def __init__(self, attr_list = []):
self.attr_list = attr_list
而且还有一个注意点,子类B、C的__init__函数中,首行就应该先调用父类A的__init__函数,__del__如是。
改造如下:
class A:
def __init__(self, attr_list = []):
self.attr_list = attr_list
def __del__(self):
del self.attr_list[:]
def addAttr(self, attr):
self.attr_list.append(attr)
class B(A):
def __init__(self):
A.__init__(self)
class C(A):
def __init__(self):
A.__init__(self)
再次分别声明变量b、c并添加1、2,打印出来看看,哈哈,果然分开了,分别是1、2.
看来还是自己对python的机制理解不够,导致出现这种使用问题,不过吃一堑长一智,还是很幸运。
相关文章推荐
- python 父类、子类,迭代器、生成器
- python子类如何调用父类的__init__方法
- Python 父类调用子类方法的问题
- python 子类继承父类的__init__方法
- Python实现子类调用父类的方法
- Python - 子类继承父类 和 Java有什么区别
- Python 子类调用父类的方法
- python中将两组数据放在一起按照某一固定顺序shuffle
- Python 父类调用子类方法
- [python相关]多类继承中子类默认继承哪个父类的构造函数__init__
- 《与小卡特一起学Python》Code3 抓取网页中的某个数据
- python中子类调用父类的初始化方法
- python获取父类的子类(遍历,递归),并循环执行所有子类的某一方法
- python子类继承父类(包括父类的初始化)
- Python中父类和子类间类属性(非实例属性)的设置获取的传递
- Python 在子类中调用父类方法详解(单继承、多层继承、多重继承)
- Python3基础 super层层调用父类的__init__方法 子类的__init__覆盖了父类的__init__的解决方法
- 配置数据的继承(默认数据),类似子类继承父类的一种方法。
- Python基础-接口与归一化设计、抽象类、继承顺序、子类调用父类,多态与多态性