2014-06-24 43 views
1

我有一個包含多個列表的類,每當有東西添加到其中一個列表時,我需要觸發對實例狀態的更改。我在下面創建了一個簡單的演示課程,試圖展示我想要做的事情。在python中爲現有的內建類方法添加一個裝飾器

假如我有一類這樣的:

class MyClass: 
    added = False 

    def _decorator(self, f): 
     def func(item): 
      added = true 
      return f(item) 
     return func 

    def __init__(self): 
     self.list = [1, 2, 3] 
     self.list.append = self._decorator(self.list.append) 

由於列表是內置的,我不能改變它的.append方法

cls = MyClass() #gives me an AttributeError since '.append' is readonly 

理想情況下,我能做到以下幾點:

cls = MyClass() 
cls.list.append(4) 
cls.added #would be true 

我該怎麼辦?子類list是否允許我以這種方式改變它的行爲?如果是這樣,我將如何在不改變方法簽名的情況下通過班級的狀態?

謝謝!

回答

2

cannot monkey-patch builtins,所以子類化是唯一的方法(實際上更好和更乾淨的恕我直言)。我會去這樣的事情:

class CustomList(list): 

    def __init__(self, parent_instance, *args, **kwargs): 
    super(CustomList, self).__init__(*args, **kwargs) 
    self.parent_instance = parent_instance 

    def append(self, item): 
     self.parent_instance.added = True 
     super(CustomList, self).append(item) 


class MyClass(object): 
    added = False 

    def __init__(self): 
     self.list = CustomList(self, [1,2,3]) 


c = MyClass() 
print c.added # False 
c.list.append(4) 
print c.added # True 
+0

謝謝,這應該適合我!我沒有看到的主要問題是如何傳入'parent_instance',但你的解決方案顯然覆蓋了這個。 –

0

這會滿足您的需求嗎?

class MyClass(object): 
    added = False 

    def __init__(self): 
     self.list = [1,2,3] 

    def append(self, obj): 
     self.added = True 
     self.list.append(obj) 



cls = MyClass() 
cls.append(4) 
cls.added #true 

它可能會有助於知道你到底想要達到什麼目的。

+0

我過於簡單化了一下。你的解決方案不起作用的原因是因爲父類('MyClass')包含多個子列表。當然,我可以爲每一個實現一個'append',比如'append_list1','append_list2'等等,但是這並不是特別優雅。 –

相關問題