我必须做什么才能使用我的自定义类型的对象作为Python字典中的键(我不想让"object id“充当键),例如
class MyThing:
def __init__(self,name,location,length):
self.name = name
self.location = location
self.length = length
我希望使用MyThing的键,如果名称和位置相同,则被视为相同的键。从C#/Java开始,我习惯了重写并提供equals和hashcode方法,并承诺不会改变hashcode所依赖的任何东西。
我必须在Python中做什么才能做到这一点?我应该这样做吗?
(在一个简单的例子中,比如这里,也许把一个(name,location)元组作为key会更好--但是考虑到我希望key是一个对象)
发布于 2011-02-05 02:55:44
您需要添加2 methods,请注意__hash__
和__eq__
class MyThing:
def __init__(self,name,location,length):
self.name = name
self.location = location
self.length = length
def __hash__(self):
return hash((self.name, self.location))
def __eq__(self, other):
return (self.name, self.location) == (other.name, other.location)
def __ne__(self, other):
# Not strictly necessary, but to avoid having both x==y and x!=y
# True at the same time
return not(self == other)
Python dict documentation在关键对象上定义了这些要求,即它们必须是hashable。
发布于 2011-02-05 04:58:30
Python2.6或更高版本中的另一种选择是使用collections.namedtuple()
--它省去了编写任何特殊方法的麻烦:
from collections import namedtuple
MyThingBase = namedtuple("MyThingBase", ["name", "location"])
class MyThing(MyThingBase):
def __new__(cls, name, location, length):
obj = MyThingBase.__new__(cls, name, location)
obj.length = length
return obj
a = MyThing("a", "here", 10)
b = MyThing("a", "here", 20)
c = MyThing("c", "there", 10)
a == b
# True
hash(a) == hash(b)
# True
a == c
# False
发布于 2021-07-30 17:36:32
我注意到在Python3.8.8(可能是更早的版本)中,你不再需要显式地声明__eq__()
和__hash__()
,这样就有机会使用你自己的类作为dict中的一个键。
class Apple:
def __init__(self, weight):
self.weight = weight
def __repr__(self):
return f'Apple({self.weight})'
apple_a = Apple(1)
apple_b = Apple(1)
apple_c = Apple(2)
apple_dictionary = {apple_a : 3, apple_b : 4, apple_c : 5}
print(apple_dictionary[apple_a]) # 3
print(apple_dictionary) # {Apple(1): 3, Apple(1): 4, Apple(2): 5}
我假设从一段时间以来,Python会自己管理它,但是我可能错了。
https://stackoverflow.com/questions/4901815
复制相似问题