2017-11-02 8 views
0

사용자 편의를 위해 __getattr____setattr__으로 액세스/수정 가능한 dict과 같은 객체를 구현하려고합니다. 클래스는 또한 다른 간단한 기능을 구현합니다.__getattr__ 및 __setattr__ 기능을 사용하여 dict-like 객체 구현

다음과 같이 내 구현은 현재, 템플릿으로 this answer 사용 :

from collections import MutableMapping 

class Dictish (MutableMapping): 
    """ 
    A dict-like mapping object. vals are always coerced to str. 
    Should provide __getattr__ and __setattr__ as aliases for 
    __getitem__ and __setitem__. 
    """ 
    def __init__ (self, *args, **kwargs): 
     self.store = dict() 
     self.update(dict(*args,**kwargs)) 

    def __getitem__ (self, key : str) -> str: 
     return self.store[key] 

    def __setitem__ (self, key : str, val : str) -> None: 
     self.store[key] = str(val) 

    def __delitem__ (self, key : str) -> None: 
     del self.store[key] 

    def __iter__ (self): 
     return iter(self.store) 

    def __len__ (self) -> int: 
     return len(self.store) 

    def __repr__ (self) -> str: 
     return repr(self.store) 

    # works fine by itself, but goes into infinite recursion 
    # when __setattr__ is defined 
    def __getattr__ (self, attr : str) -> str: 
     return self.__getitem__(attr) 

# def __setattr__ (self, attr : str, val : str) -> None: 
#  self.__setitem__(attr,val) 

답변

0

내가 쓰고 질문을 공식화했다, 나는 답을 발견 (나에게 많이 발생). 아마 이것은 다른 사람을 도울 수 있습니다.

def __getattr__ (self, attr : str) -> str: 
    return self.__getitem__(attr) 

def __setattr__ (self, attr : str, val : str) -> None: 
    if attr == 'store': 
     super().__setattr__(attr,val) 
    else: 
     self.__setitem__(attr,val) 

키가 store 속성이 밖으로 분리 재귀를 방지하기 위해 기본 클래스에서 호출해야한다는 것입니다 :

나를 위해 솔루션은 다음이었다. 아주 간단하지만 쉽게 놓칠 수있었습니다!

UPDATE :

난 당신이 store을 유지하지 않으려는 속성을 추가하기위한 기능을 추가 (즉, 속성의 일반적인 의미를.). 나는 또한 OrderedDictstore을 구현하지만, 이것은 단지 내 사용 사례입니다. 분명히 set_inst_attr 예외 임시/자리 표시 자입니다.

from collections import MutableMapping, OrderedDict 

class ODictish (MutableMapping): 
    """ 
    An OrderedDict-like mapping object. 
    Provides __getattr__ and __setattr__ as aliases for __getitem__ 
    and __setitem__. 
    Attributes which you do not want to keep in 'store' can be set with 
    self.set_inst_attr. 
    """ 
    def __init__ (self , od=None): 
     if od is None: od = OrderedDict() 
     super().__setattr__('store', OrderedDict(od)) 

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

    def __setitem__ (self, key, val): 
     self.store[key] = val 

    def __delitem__ (self, key): 
     del self.store[key] 

    def __iter__ (self): 
     return iter(self.store) 

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

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

    def __getattr__ (self, attr): 
     if attr in vars(self): 
      return vars(self)[attr] 
     return self.__getitem__(attr) 

    def __setattr__ (self, attr, val): 
     if attr in vars(self): 
      self.set_inst_attr(attr,val) 
     else: 
      self.__setitem__(attr,val) 

    def set_inst_attr (self, attr, val): 
     if attr == 'store': 
      raise Exception("Don't do that.") 
     super().__setattr__(attr,val) 

    def move_to_end (self, key, last=True): 
     self.store.move_to_end(key,last) 
+0

모든 권장 사항 및/또는 견적을 환영합니다! – nivk