2011-03-03 7 views
11

누구든지 파이썬에서 사전 객체의 변경 사항을 추적하는 쉬운 방법을 알고 있습니까? 나는 고급 수준에서 무서운 일을하기 때문에 사전을 변경하는 경우에는 기본적으로 Observer/Notify를 수행하는 함수를 호출하기 위해 몇 가지 메소드를 사용한다.파이썬 속성 변경 리스너 패턴

class MyClass(object): 
    def update(self, item): 
     changed = False 

     if(self.my_dict.has_key(item.id)): 
      self.my_dict[item.id] = item 
      changed = True 

     if(changed): 
      self.notify() 

내가 피하려고하는 것은 모든 추적 (부울 설정) 코드입니다. 변경 사항을 추적하는 더 쉬운 방법이 있었으면 좋겠다. 이것은 간단한 경우이지만, 변경된 플래그를 설정해야하는 더 복잡한 논리가있을 수 있습니다.

+0

if self.my_dict {self.my_dict [item.id] = item; self.notify()}'? (중괄호와 세미콜론을 사용하지 말고, 주석은 줄 바꿈을 먹는다) – delnan

답변

12

당신은 dict 클래스에서 파생 및 변경에 콜백을 추가 할 수 있습니다. 사전을 변경하는 메소드를 덮어 쓸 필요가 있습니다.

class NotifyDict(dict): 
    __slots__ = ["callback"] 
    def __init__(self, callback, *args, **kwargs): 
     self.callback = callback 
     dict.__init__(self, *args, **kwargs) 
    def _wrap(method): 
     def wrapper(self, *args, **kwargs): 
      result = method(self, *args, **kwargs) 
      self.callback() 
      return result 
     return wrapper 
    __delitem__ = _wrap(dict.__delitem__) 
    __setitem__ = _wrap(dict.__setitem__) 
    clear = _wrap(dict.clear) 
    pop = _wrap(dict.pop) 
    popitem = _wrap(dict.popitem) 
    setdefault = _wrap(dict.setdefault) 
    update = _wrap(dict.update) 
+0

이 작품은 참조 유형에주의를 기울여야 만합니다 ... – Nix

+0

@Nix - 조심성있는 방법, 왜? 설명해 주시겠습니까? –

+3

@VijayVaradan 이것은 첫 번째 수준의 속성 변경에만 작동합니다. 그래서 만약 내가'obj'를 가지고 있고'dict'을 가지고 있고 그 사전이 수정되면 그 변화는 집어지지 않을 것입니다. 그것은 단지'obj.xyz'를 집어 올릴 것입니다, 그것은 의미가 있습니까? – Nix

0

서브 클래스 dict__setitem__을 오버라이드하고 항목을 실제로 저장했는지 확인한 후 dict.__setitem__으로 전화를 걸어 확인하십시오.

class Notifier(dict): 
    def __setitem__(self, key, value): 
     print 'Something is being set!' 
     dict.__setitem__(self, key, value) 
+0

그러면'Notifier'를 어떻게 사용하겠습니까? 나는'self .__ member' 값이 변할 때를 알고 싶습니다. 'Notifier'가 그 객체에 캡슐화되어 있습니까? 이것이 어떻게 사용되는지에 대해 확장 할 수 있습니까? – IAbstract