如何在 Python 中的一个字典中包含来自不同 类 的不同对象?
How to have different objects from different classes in one dict in Python?
我对带有自定义对象的字典有疑问。在字典中,我知道键必须是不可变的,所以如果我想使用自定义 class,我必须定义它的哈希函数。 python 中的哈希文档建议您在 equal dunder 方法的元组上使用哈希函数。因此,例如,我定义了自定义 class temp:
class temp():
def __init__(self,value):
self.value = value
def __hash__(self):
return hash(self.value)
def __eq__(self,other):
return self.value == other.value
def __lt__(self,other):
return self.value < other.value
这样我就可以得到它们 key:value 对,例如 temp(1):1。所以我的问题。在 python 中,你可以在同一个字典中有不同的类型。所以我声明了这个字典:
myDict={ temp(1):1, temp(2):2, 'a':1,1:1, (1,2):1, True:1 }
我面临的问题是 int:int 和 bool:int 配对出现错误,告诉我错误:
'bool'对象没有属性'value'
或
'int'对象没有属性'value'
有人可以向我解释为什么会这样吗?如果我在字典中也有不同的 class ,也会发生同样的问题。因此来自汽车 class 的对象会给出此错误:
'cars'对象没有属性'value'
奇怪的是,在我的测试中,我发现如果键是元组或浮点数,它工作正常。
任何帮助将不胜感激。我想知道为什么会发生错误以及如何解决它。我的主要目标是学习如何使用我的字典,其中包含来自不同 classes 的各种对象。
您的 eq 方法需要检查另一个对象是否为同一类型:
def __eq__(self,other):
if not isinstance(other, temp):
return NotImplemented
return self.value==other.value
也就是说,我强烈建议在这种情况下使用 dataclasses。他们为您定义了 init、eq 和 (if frozen=True
) hash,这有助于避免此类问题。
问题发生在 运行 __eq__
和 __lt__
dunder 方法时。您可以通过 运行:
重现相同内容
temp(1) == 1
出现此问题是因为 __eq__
将 other
接收为 1,而值 1 没有 .value
,但您尝试在此处使用它:
return self.value == other.value
如果您只是使用其他进行比较,它应该有效:
class temp():
def __init__(self,value):
self.value = value
def __hash__(self):
return hash(self.value)
def __eq__(self,other):
return self.value == other
def __lt__(self,other):
return self.value < other
您可以这样定义 __eq__
方法:
def __eq__(self, other):
if other is None:
return False
if self.__class__ != other.__class__:
return False
return self.value == other.value
Strangely enough in my tests, I found that if the key is a tuple or a float, it works fine.
至于第二个问题,这与dict
的工作原理有关。
对于每个键,dict
的实例检查键的哈希值是否存在。如果是,则它检查与具有相同散列的其他键是否相等。在这里,相等性检查是检查它们是否基本上是相同的键(因此是相同的散列)。如果相等性检查失败,则认为键不同。
如果没有散列冲突,则不进行相等性检查。因此,当您使用 tuple
作为键时,例如 (1, 2)
,它的 hash((1, 2)) = 3713081631934410656
在 dict
中尚不存在。因此没有错误。
我对带有自定义对象的字典有疑问。在字典中,我知道键必须是不可变的,所以如果我想使用自定义 class,我必须定义它的哈希函数。 python 中的哈希文档建议您在 equal dunder 方法的元组上使用哈希函数。因此,例如,我定义了自定义 class temp:
class temp():
def __init__(self,value):
self.value = value
def __hash__(self):
return hash(self.value)
def __eq__(self,other):
return self.value == other.value
def __lt__(self,other):
return self.value < other.value
这样我就可以得到它们 key:value 对,例如 temp(1):1。所以我的问题。在 python 中,你可以在同一个字典中有不同的类型。所以我声明了这个字典:
myDict={ temp(1):1, temp(2):2, 'a':1,1:1, (1,2):1, True:1 }
我面临的问题是 int:int 和 bool:int 配对出现错误,告诉我错误:
'bool'对象没有属性'value'
或
'int'对象没有属性'value'
有人可以向我解释为什么会这样吗?如果我在字典中也有不同的 class ,也会发生同样的问题。因此来自汽车 class 的对象会给出此错误:
'cars'对象没有属性'value'
奇怪的是,在我的测试中,我发现如果键是元组或浮点数,它工作正常。 任何帮助将不胜感激。我想知道为什么会发生错误以及如何解决它。我的主要目标是学习如何使用我的字典,其中包含来自不同 classes 的各种对象。
您的 eq 方法需要检查另一个对象是否为同一类型:
def __eq__(self,other):
if not isinstance(other, temp):
return NotImplemented
return self.value==other.value
也就是说,我强烈建议在这种情况下使用 dataclasses。他们为您定义了 init、eq 和 (if frozen=True
) hash,这有助于避免此类问题。
问题发生在 运行 __eq__
和 __lt__
dunder 方法时。您可以通过 运行:
temp(1) == 1
出现此问题是因为 __eq__
将 other
接收为 1,而值 1 没有 .value
,但您尝试在此处使用它:
return self.value == other.value
如果您只是使用其他进行比较,它应该有效:
class temp():
def __init__(self,value):
self.value = value
def __hash__(self):
return hash(self.value)
def __eq__(self,other):
return self.value == other
def __lt__(self,other):
return self.value < other
您可以这样定义 __eq__
方法:
def __eq__(self, other):
if other is None:
return False
if self.__class__ != other.__class__:
return False
return self.value == other.value
Strangely enough in my tests, I found that if the key is a tuple or a float, it works fine.
至于第二个问题,这与dict
的工作原理有关。
对于每个键,dict
的实例检查键的哈希值是否存在。如果是,则它检查与具有相同散列的其他键是否相等。在这里,相等性检查是检查它们是否基本上是相同的键(因此是相同的散列)。如果相等性检查失败,则认为键不同。
如果没有散列冲突,则不进行相等性检查。因此,当您使用 tuple
作为键时,例如 (1, 2)
,它的 hash((1, 2)) = 3713081631934410656
在 dict
中尚不存在。因此没有错误。