我正在编写字典,其中用户定义的类型对象是键,我不明白为什么对于下面的代码,即使下面的对象相等,python解释器(2.7)也不会抛出错误:
class DTest:
def __init__(self,name):
self.name = name
def __eq__(self,other):
return self.name == other.name
def __hash__(self):
return hash(self.name)
ob = DTest('kkk')
ob1 = DTest('kkk')
dict = {ob:1,ob1:2}
< P.S.:我是C++开发人员,开始从事Python
针对您在评论中提出的问题,下面的示例说明了为什么可变类型通常是字典键的坏主意:
到目前为止一切正常,但是如果钥匙发生了变异。。。你知道吗
现在,字典不“认为”关键是在字典里。你知道吗
但实际上,关键是。。。你知道吗
现在,使用户定义的对象不可变并不是世界上最简单的事情,但是您真正关心的是dict键是不可变的。具体来说,您希望确保在
__hash__
和__eq__
中使用的dict键的属性是不可变的,或者以某种方式防止更改。你知道吗最简单但最不灵活的方法是使用引用相等作为
__eq__
测试(默认),并使用id(self)
作为__hash__
实现。这将确保即使发生了变异,也能找到密钥。缺点是,在字典中查找键的唯一方法是如果已经有了对该对象的引用。你知道吗另一种方法是,在某个地方将对象用作密钥之后,不要对该对象进行突变。可能不是最直观或最强大的,但肯定会工作。你知道吗
另一种方法是使用相关的用户定义对象状态创建一个不可变对象,并将其用作键。有点浪费内存,但很简单,可以完成工作。你知道吗
另一种可能是对重要属性(作为
__eq__
和__hash__
方法的一部分进行评估的属性)使用描述符,以防止它们容易被修改。你知道吗我相信还有很多其他的方法,所以了解在字典中查找键的过程是很重要的。你知道吗
如果你检查字典里的项目数,它只有1个。你知道吗
结果为1。你知道吗
Python悄悄地覆盖上一个条目。注意,这与C++不同,其中第二个键将不被插入。你知道吗
相关问题 更多 >
编程相关推荐