2013-07-15 38 views
3

我上课的结构是这样的:加入字段的值

class A(object): 
    array = [1] 

    def __init__(self): 
     pass 

class B(A): 
    array = [2, 3] 

    def __init__(self): 
     super(B, self).__init__() 

class C(B): 
    array = [4] 

    def __init__(self): 
     super(C, self).__init__() 
     print array 

当我做:

c = C() 

我希望它加入他们在继承顺序排列的所有领域。并打印[1,2,3,4]。我怎样才能做到这一点?

回答

2

为了使类修改其类的类定义时(不包括每个类定义样板代码)属性,你需要一个类装饰或元类。

如果您使用类装饰器,那么您将不得不单独修饰每个类。

如果使用元类,class A的元类将class Bclass C继承,所以你只需要修改class A

class MetaA(type): 
    def __init__(cls, name, bases, clsdict): 
     super(MetaA, cls).__init__(name, bases, clsdict) 
     for base in bases: 
      if hasattr(base, 'array'): 
       cls.array = base.array + cls.array 
       break 

class A(object): 
    __metaclass__ = MetaA 
    array = [1] 

    def __init__(self): 
     pass 

class B(A): 
    array = [2, 3] 

    def __init__(self): 
     super(B, self).__init__() 

class C(B): 
    array = [4] 

    def __init__(self): 
     super(C, self).__init__() 

产量

print(A.array) 
# [1] 

print(B.array) 
# [1, 2, 3] 

print(C.array) 
# [1, 2, 3, 4] 
4

那么当您在每个类中定义array时,它将覆盖继承的类的值。

如果要这样做,请更改类定义,并将array初始化添加到每个类的__init__(self)函数中。

I.e.

class A(object): 
    array = [1] 
    def __init__(self): 
     pass 

class B(A): 
    def __init__(self): 
     super(B, self).__init__() 
     self.array += [2,3] 

class C(B): 
    def __init__(self): 
     super(C, self).__init__() 
     self.array += [4] 
     print self.array 
+1

有这样或不在类构造器中写入一些东西,它会为所有的子元素加入'array'。 – bobby

+3

这不是一个好的解决方案,因为它会修改'array'的基类的值,而不仅仅是为子类创建联合版本。在你实例化'C'之后,'A.array'也将等于'[1,2,3,4]'。另外,如果你实例化'C'两次,'A.array'将变成'[1,2,3,4,4]',等等。 – BrenBarn