2012-07-26 161 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