2017-11-02 4 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に保つためにしたくない属性追加するための機能を追加しました(つまり、属性の通常の意味を。)。私もstoreOrderedDictとして実装しましたが、これは私の使用例です。明らかに、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

関連する問題