一个python类,它是项目的1-1映射,继承自dict

时间:2018-04-16 20:01:04

标签: python python-3.x class dictionary inheritance

我从dict类继承并尝试对项目进行1对1的映射。

而不是key:value,我正在尝试实现给定的 setitem key1:key 2,key2:key1也被添加。 如果其中任何一个键已存在,则应在添加对之前弹出它们。我该如何实施 setitem

init 应该能够构建一个空映射或来自给定字典的映射

有什么想法吗?感谢

class Mapping(dict):
    def __init__(self, Map = None):
        if Map = None:
            Map = dict()
        else:
            self.update(Map)

    def __repr__(self):
        return "Mapping({})".format(dict.__repr__self)
    def pop(self):
        return self.pop   #??? How can I pop a key and also pop the key it maps to?
    def __setitem__(self, key1,key2):
        self.__dict__[key1] = key2
        self.__dict__[key2] = key1

2 个答案:

答案 0 :(得分:0)

pop将一个键作为参数并返回与之关联的值。因此,从弹出key1获取值,并将其作为key2弹出。

您可以self.__dict__.pop(self.__dict__.pop(key))

答案 1 :(得分:0)

您可以尝试这样做:

from collections.abc import MutableMapping

# We need to implement those method: __getitem__, __setitem__, __delitem__, __iter__, __len__

class TwoWayDict(MutableMapping):

    __slots__ = '__dict__'

    def __init__(self, *args, **kwargs):
        self.__dict__.update(*args, **kwargs)
    def __getitem__(self, key):
        return self.__dict__[key]
    def __setitem__(self, key, value):
        self.__dict__[key] = value
        self.__dict__[value] = key
    def __delitem__(self, key):
        self.__dict__.__delitem__(self[self[key]])            
        self.__dict__.__delitem__(self[key])  # this do not work if key == value
    def __iter__(self):
        return iter(self.__dict__)
    def __len__(self):
        return len(self.__dict__)
    def get(self, key, default=None):
        return self[key] if key in self else default
    def __str__(self):
        return str(self.__dict__)

试验:

a = TwoWayDict()
a['key1'] = 'key2'
print(a)
print(a['key1'])
print(a['key2'])
print(len(a))
for key, val in a.items():
    print(key, val)

结果:

{'key1': 'key2', 'key2': 'key1'}
key2
key1
2
key1 key2
key2 key1

请注意,长度和迭代可能不明确。如果您不想显示重复键,则需要在dict项中找到该键并返回相应的键。对于pop,您可以使用SW Williams提出的解决方案。

编辑:如果你真的需要从dict继承(可能是一个任务......)不要忘记实现更新,因为它将绕过__setitem__并进入dict。此外,如果您有一个1对1的密钥地图,则需要在__del____pop__函数中处理此问题。