繁体   English   中英

__hash __,__ eq__和“ in”运算符

[英]__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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM