Python 继承的基类变量
我有一个叫做 Base
的类,下面有两个子类。我的想法是创建一个模型,里面包含所有的数据,然后把这些数据放到其中一个子类里。接着,我会调用一个方法来设置每个子类的头部信息,然后把模型里的数据复制到子类的实例中。不过,我发现当我在第一个类的实例(这里是 a)上调用 add_header
方法时,第二个实例 b 也得到了这个头部信息。这让我有点困惑,因为我以为不同的类实例之间是互不影响的。我的问题是,为什么会这样?有没有办法避免这种情况呢?
class Base(object):
__model__ = None
headers = ['base_header','base_header2']
def add_header(self, *args):
for h in args:
self.headers.append(h)
def set_header_values(self):
for h in self.headers:
setattr(self, h, getattr(self.__model__, h))
class ChildOne(Base):
def __init__(self, model):
self.__model__ = model
class ChildTwo(Base):
def __init__(self, model):
self.__model__ = model
class Model(object):
foo = 'bar'
m = Model()
a = ChildOne(m)
b = ChildTwo(m)
a.add_header('tralala')
print b.headers // Output ['base_header','base_header2','tralala']
1 个回答
3
“在第一个类实例(这里是 a)调用 add_header 方法后,b 也得到了这个头部信息。”
这是因为这两个实例共享了同一个变量 headers。
所以,headers 应该是实例变量,而不是类变量。
class Base(object):
__model__ = None
def __init__(self):
self.headers = []
def add_header(self, *args):
for h in args:
self.headers.append(h)
def set_header_values(self):
for h in self.headers:
setattr(self, h, getattr(self.__model__, h))
class ChildOne(Base):
def __init__(self, model):
super(ChildOne, self).__init__()
self.__model__ = model
class ChildTwo(Base):
def __init__(self, model):
super(ChildTwo, self).__init__()
self.__model__ = model
class Model(object):
foo = 'bar'
m = Model()
a = ChildOne(m)
b = ChildTwo(m)
a.add_header('tralala')
print a.headers
print b.headers
输出
['tralala']
[]
补充说明
在 Python 中,类变量和实例变量常常会让人困惑。来看下面这个例子:
class A:
l =[]
class B:
l =[]
x = A()
y = A()
x.l.append(1)
print 'class A ', A.l, x.l, y.l
x = B()
y = B()
x.l = [1]
print 'class B ', B.l, x.l, y.l
输出
class A [1] [1] [1]
class B [] [1] []
这两个例子在访问数据成员 'l' 时看起来很相似,但第一个例子修改了已经存在的类变量,而第二个例子则创建了一个新的实例变量。
在你的例子中,如果你用 self.headers = [...]
来赋值,而不是 self.append(...)
,那么你的输出结果会不同。
另外,问题中的 __model__
属性和这个问题没有关系。