"映射"dictonary类中的错误

Geo*_*ris 3 python

我正在尝试创建一个简单的映射类,其中当键为1-1时,例如key1:key2, key2:key1.当我检查班级是否等于我输入的值时,我遇到了一个错误,我应该得到True但我会继续False.

>>> m=Mapping()
>>> m[2]=3
>>> m
Mapping({2: 3, 3: 2})
>>> m==Mapping({2: 3, 3: 2})
False
Run Code Online (Sandbox Code Playgroud)

我不确定我做错了什么,我的代码在下面,任何帮助将不胜感激.

class Mapping():
    def __init__(self, dic={}):
        self.Dict = dict(dic)
    def __repr__(self):
        return "Mapping({})".format(self.Dict)
    def __getitem__(self, loc=0):
        return self.Dict[loc]
    def pop(self, popn=0):
        popm = self.Dict[popn]
        self.Dict.pop(popn, None)
        self.Dict.pop(popm, None)
    def __setitem__(self, x, y):
        self.Dict[x]=y
        self.Dict[y]=x
Run Code Online (Sandbox Code Playgroud)

tob*_*s_k 6

您的Mapping类必须实现__eq__魔术方法才能==正常工作.假设两个Mappings相等,如果Dict相等,你可以试试这样的:

    def __eq__(self, other):
        if isinstance(other, Mapping):
            return self.Dict == other.Dict
        return False
Run Code Online (Sandbox Code Playgroud)

如果没有这个,==将回过头来检查那些是否是同一个实例,即是什么is.


通常,在实现时__eq__,您也会实现该__hash__方法,因此两者是一致的.再一次,你可以简单地委托self.Dict为哈希,但dict不是哈希(有充分的理由,见下文),但你可以哈希项目:

    def __hash__(self):
        return hash(frozenset(self.Dict.items()))
Run Code Online (Sandbox Code Playgroud)

没有__hash__,你可以例如不使用你的Mapping类作为另一个字典中的键.然而,这种设置是有问题的,因为它dict是可变的,因此hash(m)可能在使用之间改变,使得无法Mapping从以后dictset之后检索.

  • @NikolayProkopyev看到我的编辑.但是,在这种特殊情况下,实现`__hash__`实际上没有意义,就像"普通"可变`dict`一样. (2认同)