2011-05-15 4 views
2

파이썬리스트를 서브 클래스 화하고,리스트가 바뀌면 특정 다른 오브젝트에게 알리는 클래스를 작성하고 싶습니다. 오버라이드 (override) 할 필요가 많은 방법이 있기 때문에, 내가 대신 목록을 변경하는 모든 방법을 재정의이 같은 솔루션을 선택했다 :파이썬리스트 오브젝트의 특별한 메소드를 대체하는 것

이 "추가"하지만 같은 특별한 방법에 대한 같은 방법 작동
destructiveMethods = ["__setitem__", 
         "__setslice__", 
         "__delitem__", 
         "__delslice__", 
         "append", 
         "extend", 
         "remove", 
         "reverse", 
         "sort"] 

class OwnedList(list): 
    def __init__(self, owner, initValue=[]): 
     super(OwnedList, self).__init__(initValue) 


     def wrappedMethod(method): 
      def resultMethod(*args, **kwargs): 
       ret = method(*args, **kwargs) 
       self.owner.notify() 
       return ret 
      return resultMethod 

     self.owner = owner 
     for m in destructiveMethods: 
      setattr(self, m, wrappedMethod(getattr(self, m))) 

"__setitem__". 그들을 위해, 나는 단순히 오래된 방법을 얻는다.

나는 말, 추가의 값을 인쇄하는 경우, 내가 좋아하는 뭔가를 얻을 것으로 나타났습니다 :

<built-in method append of list object at 0x267a7a0> 

그러나 __setitem__이 내가 무엇을 얻을 것입니다 (바닐라 목록) :

<method-wrapper '__setitem__' of list object at 0x266fd40> 

아마도 내 문제와 관련이 있습니다.

도움을 주시면 감사하겠습니다. 내가해야 할 일을 성취 할 수있는 더 좋은 방법을 안다면, 그것에 대한 당신의 생각을 공유하십시오. 감사.

UPDATE : 뭔가 다른 내가 OwnedList 개체에 직접 __setitem__ 호출 나타났습니다 예상대로 작동하지만 괄호를 사용하는 것은하지 않습니다.

답변

2

특수 메서드는 개체 유형에만 정의 할 수 있으며 source 인스턴스에는 정의 할 수 없습니다.

당신은 생성자에서 클래스 본문에 직접 특별한 방법을 정의하고 있지 즉, A을 적용해야

>>> class A(object): 
...  __getitem__ = lambda self,i: 42 
>>> A()[0] 
42 

>>> class B(object): 
...  def __init__(self): 
...    self.__getitem__ = lambda self,i: 42 
>>> B()[0] 
TypeError: 'B' object does not support indexing 

비교.

+0

감사합니다. 매력처럼 작동합니다. – Elektito

관련 문제