2015-05-22 124 views
2

我GOOGLE了,发挥了一段时间,但没有结果试图做这样的事情:Python类属性和子类

class A(object): 
    cl_att = 'I am an A class attribute' 

class B(A): 
    cl_att += ' modified for B type' 

class C(A): 
    cl_att += ' modified for C type' 


instA = A() 
print insAt.cl_att 
>>> I am an A class attribute 

instB = B() 
print instB.cl_att 
>>> I am an A class attribute modified for B type 

instC = C() 
print instC.cl_att 
>>> I am an A class attribute modified for C type 

print instA.cl_att 
>>> I am an A class attribute 

总而言之一句话我希望能够“使用,然后覆盖”一我的父类的类属性。

回答

1

假设你只有一个父类,你可以使用在回答最后在你的子类中定义的inherit_and_append装饰,以获得期望的结果,就像这样:

class A(object): 
    cl_att = 'I am an A class attribute' 

@inherit_and_append('cl_att') 
class B(A): 
    cl_att = ' modified for B type' 

@inherit_and_append('cl_att') 
class C(A): 
    cl_att = ' modified for C type' 

如果有更高级的要求或条件,您可以进一步扩展装饰器。

class inherit_and_append(object): 
    def __init__(self, *attrs): 
     super(inherit_and_append, self).__init__() 

     self._attrs = attrs 

    def __call__(self, klass): 
     parent = klass.__bases__[0] # Assuming you have a single parent class 
     for attr in self._attrs: 
      if not hasattr(parent, attr): 
       raise AttributeError("'{}' class has no '{}' attribute".format(parent.__name__, attr)) 

      parent_value = getattr(parent, attr) 
      klass_value = getattr(klass, attr) 
      setattr(klass, attr, parent_value + klass_value) 

     return klass 
7

参考父类的属性,并连接到它:

class A(object): 
    cl_att = 'I am an A class attribute' 

class B(A): 
    cl_att = A.cl_att + ' modified for B type' 

class C(A): 
    cl_att = A.cl_att + ' modified for C type' 

类机构执行很像功能,与形成类属性的本地名称。 cl_att不存在于新的'函数'中,用于创建BC的实体,因此您需要直接引用基类上的属性。

演示:

>>> class A(object): 
...  cl_att = 'I am an A class attribute' 
... 
>>> class B(A): 
...  cl_att = A.cl_att + ' modified for B type' 
... 
>>> class C(A): 
...  cl_att = A.cl_att + ' modified for C type' 
... 
>>> A.cl_att 
'I am an A class attribute' 
>>> B.cl_att 
'I am an A class attribute modified for B type' 
>>> C.cl_att 
'I am an A class attribute modified for C type'