2016-11-25 2 views
0

独自のメソッドセットを持つカスタム辞書クラスNewDictがあります。このカスタム辞書のすべてのキーの値がクラスNewDictであるように別のカスタム辞書クラスCustomDictionaryを作成したいと思います。カスタム辞書の値の種類を制限していますか?

は、今私が持っている:

from collections import OrderedDict 
from NewDict import NewDict 

class CustomDictionary(OrderedDict): 
    def __init__(self, *args, **kwargs): 
    super(CustomDictionary, self).__init__(*args, **kwargs) 

ので、私はこのクラスはそれのすべての値がNewDictであることを知っているので、追加する必要がありますか?

class NewDict(dict): 
    _keys = ['my_key_1', 'my_key_2', ...] 
    def __init__(self, **kwargs): 
    for key in self._keys: 
     if key in kwargs: 
     self[key] = kwargs[key] 
     else: 
     self[key] = None 
    <various methods> 
+0

NewDictモジュールを表示できますか? – ettanany

+1

あなたは、次の抽象クラス 'collections.MutableMapping'または' collections.Mapping'に実装する必要があります。 –

+0

クラス内のすべての値が 'NewDict'型であることを知っているクラスを定義してください。 (私はあなたが 'CustomDictionary'を意味する"クラス "と仮定します)。 – martineau

答えて

1

私のコメントで示唆したように、collections.MutableMappingを実装できます。

ここには内部辞書を使用した例があります。古典的なdictまたは他の辞書のようなクラスを使用できます。

class NewDict(dict): 
    pass 


import collections 


class CustomDictionary(collections.MutableMapping): 
    """ A dictionary which contains only ``NewDict`` values. """ 

    def __init__(self, *args, **kwargs): 
     self._data = dict() # or collections.OrderedDict, etc. 
     self.update(*args, **kwargs) 

    def __iter__(self): 
     return self._data.__iter__() 

    def __setitem__(self, key, value): 
     if not isinstance(value, NewDict): 
      raise TypeError(repr(type(value))) 
     self._data.__setitem__(key, value) 

    def __delitem__(self, key): 
     self._data.__delitem__(key) 

    def __getitem__(self, key): 
     return self._data.__getitem__(key) 

    def __len__(self): 
     return self._data.__len__() 

Or Duanによって提示されるように、タイプチェックを行うことができます。私はNewDictというサブクラスのインスタンスを許可するために、isinstanceを使用する方が好きです。

  • 長所:collections.MutableMappingはそうでgetupdatesetdefaultなど、すべての古典的なdictのメソッドを実装します。
  • 短所:この実装では、クラスにいくつかのマジックメソッドを挿入する抽象基本クラスを使用します。しかし、それらは文書化されている。

その後、あなたは他の辞書のように、この辞書を使用することができます:上記の辞書と

def __str__(self): 
     return self._data.__str__() 

    __repr__ = __str__ 

:あなたは、次のメソッドを追加する場合は、値を印刷することができ

custom_dict = CustomDictionary() 
custom_dict["key1"] = NewDict() 
custom_dict["key1"]["my_key_1"] = 3.14 

inner_dict = custom_dict["key2"] = NewDict() 
inner_dict["my_key_1"] = 2 
inner_dict["my_key_2"] = 4 

import pprint 
pprint.pprint(custom_dict) 

入手方法:

{'key2': {'my_key_2': 4, 'my_key_1': 2}, 'key1': {'my_key_1': 3.14}} 
+0

ありがとうございます。いくつかのこと。 1.)私は順序付き辞書にしたい、それを維持する変更可能なマッピングを使用していますか? 2.)どのように私はそれを設定するので、自己はself.dataではない辞書ですか? 3)これは本当に値を制限するようには見えませんが、他のものに割り当てられないようにしています....最後に重要ではないが、設定値からメソッドを使用する方法を知るためにオートコンプリートを更新できますか? – SumNeuron

+0

@SumNeuron:広告掲載オーダーまたはキーオーダーを希望しますか?最初のものは 'self._data = collections.OrderedDict()'です。 –

+0

キーが挿入されて生成されていない可能性が最も高いですか? self._dataはself ["key"]を呼び出すことができますか?self._data ["key"]とタイプする必要がありますか? – SumNeuron

1

これは、__setitem__メソッドをオーバーライドすることで実現できます。

class CustomDictionary(dict): 
    def __setitem__(self, key, value): 
     if type(value) != NewDict: 
       raise TypeError("Can't do that :(") 

これは、各挿入のためのいくつかのオーバーヘッドを持っていることに注意してください:これはのpython3例です。

+1

'TypeError'を呼び出す方が適切です。 –

+0

はい、この新しいクラス内のオートコンプリート以外は、値にアクセスするときに 'NewDict'クラスメソッドを表示しません.... – SumNeuron

+0

plus1、私の答えを更新しました@LaurentLAPORTE –

関連する問題