[英]__hash__, __eq__ and “in” operator
我见过很多问题__eq__
, __hash__
和他们的关系,即使我坚持了一个令人惊讶的现象,我想澄清。
我有一个词典team
其中包含很多player
实例作为其键。 类player
本身很__hash__
,但包含__hash__
和__eq__
。 我可能还会注意到player
包含作为字典的属性,我相信这是问题的原因。
无论如何,我的代码如下:
if player in team.keys():
name, height = team[player]
怪异的现象是,当player in team
返回True
(因此条件已满足并且执行了下一行),第二行引发KeyError
。 我不能弄清楚in
工作原理如何,而键没有正确地散列。
有什么建议么?
player
类包括以下魔术方法。 cnfg_dict
是一本具有几个用户指定配置的字典,其中的required_attrs
用于区分player
实例(可以说...)。
def __init__(self, cnfg_dict):
self.config_dict = cnfg_dict
self.required_attrs = ['attr1', 'attr2']
def __eq__(self, other):
return all([self.config_dict[attr] == other.config_dict[attr] for attr in self.required_attrs])
def __ne__(self, other):
required_attrs = ['dt', 'author']
return any([self.config_dict[attr] != other.config_dict[attr] for attr in required_attrs])
def __repr__(self):
return str([str(a)+'='+str(self.config_dict[a]) for a in self.required_attrs])
def __hash__(self):
return hash(repr(self))
我不满意您的大赌注,即彼此相等的对象将具有相同的repr函数。 当然,如果您要处理数字,则有风险。 这是一个例子:
[in] >>> a = {'name': 'Zelaznik', 'height': 6}
[in] >>> b = {'name': 'Zelaznik', 'height': 6.0}
[in] >>> a == b
[out] >>> True
[in] >>> repr(a['height']) == repr(b['height'])
[out] >>> False
我敢打赌,您正遇到球员身高问题。
这是解决哈希函数的快速方法:
def __hash__(self):
dct = self.confg_dict
keys = self.required_attr
return hash(tuple([dct[k] for k in keys]))
看起来您正在处理具有预定键集的“ Player”类,在这种情况下,您可以使用namedtuple使自己的生活更轻松。
from collections import namedtuple
Player = namedtuple('Player', ('name', 'height', 'opt_attr1', 'opt_attr2'))
Player.__new__.__defaults__ = (None, None) #Sets default values for last two arguments.
https://docs.python.org/2/library/collections.html#collections.namedtuple
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.