[英]How to have different objects from different classes in one dict in Python?
I had a question about dictionaries with custom objects.我对带有自定义对象的字典有疑问。 In a dict, I know that the key has to be immutable, so if I want to use a custom class, I have to define its hash function.
在字典中,我知道密钥必须是不可变的,所以如果我想使用自定义 class,我必须定义它的 hash function。 The hash doc in python recommends you use the hash function on the tuple of the equal dunder method.
python 中的 hash 文档建议您使用 hash ZC1C4under25268E683894D1AB507Ztuple7 上的方法。 So for example, i defined the custom class temp as such:
例如,我定义了自定义 class 温度,如下所示:
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
This way I can have they key:value pair such as temp(1):1.这样我就可以拥有它们的键:值对,例如 temp(1):1。 So to my question.
所以我的问题。 In python, you can have different types in the same dict.
在 python 中,您可以在同一个字典中有不同的类型。 So I declared this dict:
所以我宣布了这个字典:
myDict={ temp(1):1, temp(2):2, 'a':1,1:1, (1,2):1, True:1 }
The problem I am facing is that I would get an error for the int:int and bool:int pairing telling me the error:我面临的问题是我会收到一个错误 int:int 和 bool:int 配对告诉我错误:
'bool' object has no attribute 'value' “布尔” object 没有属性“值”
or或者
'int' object has no attribute 'value' 'int' object 没有属性 'value'
Can someone explain to me why this is the case?有人可以向我解释为什么会这样吗? The same issue would happen if I have a different class in the dict as well.
如果我在字典中有不同的 class 也会发生同样的问题。 So an object from a cars class would give this error:
因此,来自汽车 class 的 object 会给出此错误:
'cars' object has no attribute 'value' “汽车” object 没有属性“值”
Strangely enough in my tests, I found that if the key is a tuple or a float, it works fine.奇怪的是,在我的测试中,我发现如果键是元组或浮点数,它就可以正常工作。 Any help would be greatly appreciated.
任何帮助将不胜感激。 I wanted to know why the error is happening and how I can fix it.
我想知道为什么会发生错误以及如何修复它。 MY main goal is to learn how to my one dict that has various objects from different classes.
我的主要目标是学习如何使用我的一个包含来自不同类的各种对象的字典。
Your eq method needs to check if the other object is the same type:您的 eq 方法需要检查其他 object 是否为同一类型:
def __eq__(self,other):
if not isinstance(other, temp):
return NotImplemented
return self.value==other.value
That said, I highly recommend using dataclasses for cases like this.也就是说,我强烈建议在这种情况下使用数据类。 They define init, eq, and (if
frozen=True
) hash for you, which helps avoid this sort of issue.他们为您定义了 init、eq 和(如果 freeze
frozen=True
) hash,这有助于避免此类问题。
The issue happens when running the __eq__
and __lt__
dunder methods.运行
__eq__
和__lt__
dunder 方法时会出现此问题。 You can reproduce the same by running:您可以通过运行来重现相同的内容:
temp(1) == 1
The issue happens because __eq__
receives other
as 1, and the value 1 does not have a .value
, but you're trying to use it here:出现问题是因为
__eq__
接收other
作为 1,并且值 1 没有.value
,但您尝试在此处使用它:
return self.value == other.value
If you just use other for comparisons it should work:如果您只是使用 other 进行比较,它应该可以工作:
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
You can define your __eq__
method like this:你可以像这样定义你的
__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.
奇怪的是,在我的测试中,我发现如果键是元组或浮点数,它就可以正常工作。
As for the second question, this has got to do with how a dict
works.至于第二个问题,这与
dict
的工作方式有关。 For every key, the instance of dict
checks if the hash of the key exists.对于每个键,
dict
的实例检查该键的 hash 是否存在。 If yes, then it checks for equality with other keys with the same hash.如果是,则它检查与具有相同 hash 的其他键是否相等。 Here, the check for equality is to check if they are basically the same keys (and hence the same hash).
在这里,相等性检查是检查它们是否基本上是相同的键(因此是相同的哈希)。 If the equality check fails, then the keys are deemed different.
如果相等检查失败,则认为密钥不同。
If there are no hash collisions, then no equality checks are done.如果没有 hash 冲突,则不进行相等检查。 Hence, when you used a
tuple
as a key, say, (1, 2)
, its hash((1, 2)) = 3713081631934410656
, which doesn't yet exist in the dict
.因此,当您使用
tuple
作为键时,例如(1, 2)
,其hash((1, 2)) = 3713081631934410656
尚不存在于dict
中。 Hence no error.因此没有错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.