限制自定义词典的值类型?

时间:2016-11-25 19:50:37

标签: python dictionary

我有一个自定义字典类NewDict,它有自己的方法集,但没有。我想创建另一个自定义词典类CustomDictionary,这样自定义词典中每个键的值都是类NewDict

现在我有:

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>

2 个答案:

答案 0 :(得分:1)

您可以通过覆盖__setitem__方法来实现这一目标。这是python3示例:

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

请注意,每次插入都会产生一些开销。

答案 1 :(得分: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所示,您可以进行类型检查。我更喜欢使用isinstance来允许子类NewDict

的实例
  • 优点:collections.MutableMapping实现所有经典dict方法,例如getupdatesetdefault等。
  • 缺点:此实现使用Abstract Base Classes,它在您的类中插入一些魔术方法。但他们有记录。

然后,您可以像任何其他词典一样使用此词典:

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

如果添加以下方法,则可以打印值:

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

    __repr__ = __str__

使用上面的词典:

import pprint
pprint.pprint(custom_dict)

你得到:

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