2012-07-26 63 views
10

我试图找到扩展类变量的最佳方法。希望迄今为止我提出的方法的一个例子将清楚地说明这一点。python类属性

class A(object): 
    foo = ['thing', 'another thing'] 

class B(A): 
    foo = A.foo + ['stuff', 'more stuff'] 

所以我试图让子类继承和扩展父类变量。上面的方法工作,但似乎有点kludgey。我愿意接受任何建议,包括使用完全不同的方法完成类似的事情。

显然我可以继续使用这种方法,如果需要的话,但如果有更好的方法,我想找到它。

+6

是什么样的'foo',它需要一个[类属性(HTTP:// stackoverflow.com/questions/128573/)而不只是一个实例属性? (对于这个问题,考虑到列表是可变的,你可以在'__init__'时间改变*类属性。) – kojiro 2012-07-26 18:41:15

+7

恕我直言,你对我看起来很好(我想不出一个更干净的方式来做它)。顺便说一句,我会称这些“类属性”,而不是“类属性”,因为属性是不同的东西(通常由'property'内建函数/装饰器创建)。 – mgilson 2012-07-26 18:41:35

+0

@kojiro他不是指那些属性,他只是指属性。 – Julian 2012-07-26 18:52:18

回答

8

可以使用元类:

class AutoExtendingFoo(type): 

    def __new__(cls, name, bases, attrs): 
     foo = [] 
     for base in bases: 
      try: 
       foo.extend(getattr(base, 'foo')) 
      except AttributeError: 
       pass 
     try: 
      foo.extend(attrs.pop('foo_additions')) 
     except KeyError: 
      pass 
     attrs['foo'] = foo 
     return type.__new__(cls, name, bases, attrs) 

class A(object): 
    __metaclass__ = AutoExtendingFoo 
    foo_additions = ['thing1', 'thing2'] 
    # will have A.foo = ['thing1', 'thing2'] 

class B(A): 
    foo_additions = ['thing3', 'thing4'] 
    # will have B.foo = ['thing1', 'thing2', 'thing3', 'thing4'] 

class C(A): 
    pass 
    # will have C.foo = ['thing1', 'thing2'] 

class D(B): 
    pass 
    # will have D.foo = ['thing1', 'thing2', 'thing3', 'thing4'] 
+2

不错,但违反了最不让人惊讶的原则。也许分配给'__add_to_foo__',假设我们从'object'继承了一个空的'foo'。 – chepner 2012-07-26 20:38:40

+0

@chepner更好。我会改变它... – 2012-07-26 21:41:05

1

我明确地会去的实例属性。 (如果我是正确的,他们不必然是静态的你的情况?!)

>>> class A: 
...  @property 
...  def foo(self): 
...   return ['thin', 'another thing'] 
... 
>>> class B(A): 
...  @property 
...  def foo(self): 
...   return super().foo + ['stuff', 'thing 3'] 
... 
>>> B().foo 
['thin', 'another thing', 'stuff', 'thing 3'] 
+0

如果你经常访问这些数据,这并不是特别有效。你必须对'A'进行属性查找,然后每次访问'B.foo'时创建一个新列表并追加到它。再加上你仍然有这样的问题:每个子类都必须定义属性,以便检索'super()。foo'。如果任何未来的类继承自多个富有类的类,那么您就很难快速地解决问题。 – 2012-07-26 22:12:10