2014-06-14 257 views
0

所以我有Base類與兩個子類。我的想法是,我將擁有一個包含所有可以插入其中一個子類的數據的模型。然後調用一個方法在每個子類上設置標題,然後將數據從Model複製到Child類實例。但是,我發現在第一個類實例(在這種情況下a)上調用add_header方法之後,b也獲得了標題。哪一種讓我困惑,因爲我認爲發起的課程不會互相影響。我的問題是爲什麼會出現這種情況,可以避免嗎?Python繼承基類變量

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

這是有點不清楚你在做什麼,爲什麼'header'不是一個實例變量呢? – timgeb

+0

@timgeb標題包含一些「基本」標題,它們出現在兩個模型中 – Niels

回答

1

「調用add_header方法在第一類的實例後(一個在這種情況下)B還得到了標題」 由於兩個實例共享相同的變量的標頭。 頭應該是實例而非可變

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__屬性在你的問題中與問題無關。