2010-09-15 52 views
6

我有一個類叫做細胞:在自定義Python類中覆蓋默認方法的簡單方法?

class Cell: 

    def __init__(self, value, color, size): 
     self._value = value 
     self._color = color 
     self._size = size 

    # and other methods... 

Cell._value將存儲一個字符串,整數,等等。(不管我使用的對象)。我想,通常會用「價值」的對象來使用<Cell object>._value所有默認的方法,這樣我可以做的:

>>> c1 = Cell(7, "blue", (5,10)) 
>>> c2 = Cell(8, "red", (10, 12)) 
>>> print c1 + c2 
15 

>>> c3 = Cell(["ab", "cd"], "yellow", (50, 50)) 
>>> print len(c3), c3 
2 ['ab', 'cd'] 

# etc. 

我可以覆蓋所有的默認方法:

class Cell: 

    def __init__(self, value, color, size): 
     # ... 

    def __repr__(self): 
     return repr(self._value) 

    def __str__(self): 
     return str(self._value) 

    def __getitem__(self, key): 
     return self._value[key] 

    def __len__(self): 
     return len(self._value) 

    # etc. 

...但有沒有更簡單的方法?

+1

爲什麼一個整數'self._value'有能力被一個鍵索引?你有沒有嘗試過一個整數的長度?另外,這可能不應該是cocmmunity wiki:沒有人會以這種方式回答問題,我們在這裏愛我們的一些觀點。 – aaronasterling 2010-09-15 18:48:58

+2

-1:這不應該是一個維基。 – 2010-09-15 18:49:18

+0

@AaronMcSmooth'self._value'可以容納任何數據類型,所以我想擁有所有可能的方法。 – 2010-09-16 12:41:40

回答

11

如果我正確理解你,你正在尋找一種簡單的方法將對象的方法委託給該對象的屬性?

您可以通過定義一個裝飾避免一些重複性:

def delegate(method, prop): 
    def decorate(cls): 
     setattr(cls, method, 
      lambda self, *args, **kwargs: 
       getattr(getattr(self, prop), method)(*args, **kwargs)) 
     return cls 
    return decorate 

您可以再申請裝飾爲每個要委託的方法:

@delegate('__len__', '_content') 
@delegate('__getitem__', '_content') 
class MyList(object): 
    def __init__(self, content): 
     self._content = content 

spam = MyList([1,2,3,4,5]) 

len(spam) # prints "5" 

spam[0] # prints "1" 

你也許可以通過進一步簡化它修改裝飾器以將多個方法名稱作爲參數。

如果你想讓你的類充當一個完整的包裝器,你可能會重寫該類的__getattr__方法來檢查包裝的對象之前失敗。這將模仿沒有實際繼承的子類的行爲。

+0

我認爲重寫'__getattr__'更接近我所尋找的,但我也看到了裝飾器選項中的值。現在我只需要理解'__getattr__'和'__getattribute__'之間的區別:http://docs.python.org/reference/datamodel.html#object.__getattribute__ – 2010-09-16 13:28:15

0

您需要重載__add__方法才能獲得所需的c1 + c2行爲。

請參閱here瞭解它們的含義。