2017-12-20 17 views
2

dictのサブクラスを作成しています。これは文字列キーから任意の型の値にマップします。キーが正規表現である場合、キーは別々に格納され、照会されます。Python継承:オーバーライドされていないメソッドが呼び出されたときのエラーの発生

class RegexDict(dict): 
    def __init__(self): 
     super().__init__() # non-regex keys in the parent class 
     self.regex_dict = {} # regex keys in the child class 

    def __getitem__(self, key): 
     try: 
      return super().__getitem__(key) 
     except KeyError: 
      for x in self.regex_dict: 
       if re.fullmatch(x, key): 
        return self.regex_dict[x] 
     raise KeyError(key) 

    def __setitem__(self, key, value): 
     key, is_regex = key 
     if is_regex: 
      self.regex_dict[key] = value 
     else: 
      super().__setitem__(key, value) 

このクラスは(私は、継承を使用する必要が理由である)他のライブラリで使用されますので、私は、基本クラス内の非オーバーライドされたメソッドが呼び出されたときにエラーが発生することを確認します。私はこれをどのようにするべきですか?

答えて

0

あなたはcollections.abc.MutableMapping代わりの辞書から継承する必要があります。

これはギャップを自動的に埋めるだけでなく、実装する必要があることを知らせます。

__getitem____setitem__に加えて、あなたも__delitem____iter____len_を実装する必要があります。これらを合理的に実装できない場合は、たとえばそれらからのNotImplementedError(あなたのクラスの使用をたくさん制限するとしても)。

これは、内部で__getitem____setitem__(+あなたが実装したもの)だけを必要とするすべてのdictメソッドがそのまま使えるという利点があります。

+0

悲しいことに、私の経験から、* MutableMapping *は、* pandas *のような主流の場合でも、多くのlibsでは十分ではありません。さらに、これらの方法は、OPのニーズに反しているように見えます。 – pacholik

+0

これは本当に理想的なケースですが、クラスを 'pandas'で動作させる必要があります。内部的には、 'pandas'は' np.dtype() 'を呼び出しますが、残念ながらカスタム型とは互換性がありません。 –

-1

サブクラス化しないでください。オブジェクトがdictであることを第三者のライブラリに知らせるには、__class__という属性を設定します。

class RegexDict(): 
    __class__ = dict 

    def __init__(self): 
     self.non_regex_dict = {} 
     self.regex_dict = {} 

    def __getitem__(self, key): 
     try: 
      return self.non_regex_dict[key] 
     except KeyError: 
      for x in self.regex_dict: 
       if re.fullmatch(x, key): 
        return self.regex_dict[x] 
     raise KeyError(key) 

    def __setitem__(self, key, value): 
     key, is_regex = key 
     if is_regex: 
      self.regex_dict[key] = value 
     else: 
      self.non_regex_dict[key] = value 

rd = RegexDict() 
print(isinstance(rd, dict)) 
rd.clear() 

出力:

True 
Traceback (most recent call last): 
    File "libo.py", line 30, in <module> 
    rd.clear() 
AttributeError: 'RegexDict' object has no attribute 'clear' 
+0

このソリューションは、私のマシン上の 'pandas'では動作しませんでした。 'pandas'が' RegexDict'インスタンスで 'np.dtype()'を呼び出すと失敗しました。私はなぜこれがうまくいかず、継承したのに興味がありますが、Numpyのソースコードで 'np.dtype()'を見つけることができませんでした。 –

+0

@LiboYin例を挙げてください。あなたの質問を編集してください。 – pacholik

関連する問題