Python: 从字典中,如何检索对象作为键

Python: from a dict, how retrieve object as key

如果我有一个包含多个 Object:value, 的字典,我如何检索某个对象并将其用作 [key]

例如

class Obj():
    def __init__(self, value):
        self.value = value

dct = {Obj(foo):foo_value, Obj(bar):bar_value}

#How to do something like
#>>> dct[foo]
#foo_value

假设 foo_value 不能被分配为 Obj 的 属性。

到目前为止,这就是我得到的(抽象的)

class Obj():
    def __init__(self, name):
        self.name = name
    def __hash__(self):
        return hash(tuple(sorted(self.__dict__.items())))
    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        else:
            return False
    def __repr__(self):
        return str(self.name)

dct = {Obj('item1'):1, Obj('item2'):2}

print(dct.keys())
dct['item1']

和输出

dict_keys([item1, item2])
Traceback (most recent call last):
    File "C:\Users\ivan\Desktop\multi_e.py", line 197, in <module>
     dct['item1']
KeyError: 'item1'

这将不起作用,因为键不是字符串,而是 Obj 类型的对象。即使所有对象都包含该字符串 你可以这样做。将变量作为对对象的引用存储为键

x = Obj("item1")
y = Obj("item2")
dct= {x:1, y:2}

要检索您需要做的事情:

>>> dct[x]
1

使用 dict 的自定义实现怎么样?

class FieldDict(dict):
    def __getitem__(self, item):
        return dict.__getitem__(self, Obj(item))

dct = FieldDict({Obj('item1'):1, Obj('item2'):2})

print(dct.keys())
print(dct['item1'])  # prints 1

您可以使用自定义 __getitem____setitem__ 推出您自己的 dict subclass 而您 真的 不需要任何Obj class 上的复杂 __hash__ 方法,之后,__init__ 就足够了。

class Obj:
    def __init__(self, value):
        self.name = value

class MyDict(dict):
    def __setitem__(self, key, value):
        if isinstance(key, Obj):
            dict.__setitem__(self, key.name, value)
        else:
            dict.__setitem__(self, key, value)

    def __getitem__(self, key):
        if isinstance(key, Obj):
            return dict.__getitem__(self, key.name)
        return dict.__getitem__(self, key)

演示:

>>> dct = MyDict()
>>> dct[Obj('item1')] = 1
>>> dct[Obj('item2')] = 2
>>> dct
{'item1': 1, 'item2': 2}    
>>> dct['item1']
1
>>> dct[Obj('item1')]
1

我尝试了一段时间,但我想我得到了你想要的,看:

edit thanks to @user2357112

class Obj():
    def __init__(self, value):
        self.value = value

    def __eq__(self, other):
      """Override the default Equals behavior"""
      if isinstance(other, self.__class__):
          return self.value == other.value
      return False

    def __ne__(self, other):
      """Define a non-equality test"""
      return not self.__eq__(other)


    def __hash__(self):
      return id(self.value)

class Custom_dict(dict):

    def __getitem__(self, item):
      return dict.__getitem__(self, Obj(item))

x = Custom_dict()
x[Obj('asdf')] = 5
print(x['asdf'])


dct = Custom_dict({Obj('item1'):1, Obj('item2'):2})
print([key.value for key in dct.keys()])
print(dct['item1'])    

5 ['item1', 'item2']

1