我的目标是创建一个类似于元组的类,除了等式/不等式方法,因为我不想要MyTuple(1, 2, 3) == (1, 2, 3)
是True
我希望将它用于与tuple
对应词不同的词典键。我终于做到了,但我遇到了一些无法解释的奇怪行为。
我认为实现这一目标最方便的方法是继承namedtuple
。为了证明一点,首先没有特殊的(in)平等方法:
from collections import namedtuple
class MyTuple(namedtuple('MyTuple', 'a b c')):
pass
print({MyTuple(1, 2, 3): 'my-tuple', (1, 2, 3): 'just-tuple'})
Out: {MyTuple(a=1, b=2, c=3): 'just-tuple'}
有点奇怪 python3.6 保留第二个值的第一个键,但是它们是相等的,所以我觉得很好。
现在我实现了(in)相等方法和意外发生的事情:
class MyTuple(namedtuple('MyTuple', 'a b c')):
def __eq__(self, other):
return isinstance(other, MyTuple) and tuple(self) == tuple(other)
# No, it is not __ne__ that is missing...
print({MyTuple(1, 2, 3): 'my-tuple', (1, 2, 3): 'just-tuple'})
输出:
Traceback (most recent call last)
----> 7 print({MyTuple(1, 2, 3): 'my-tuple', (1, 2, 3): 'just-tuple'})
TypeError: unhashable type: 'MyTuple'
我没有删除__hash__
方法,所以它怎么会消失?
它 使用额外的重新实现的哈希函数,但是:
class MyTuple(namedtuple('MyTuple', 'a b c')):
def __eq__(self, other):
return isinstance(other, MyTuple) and tuple(self) == tuple(other)
def __hash__(self):
return hash(tuple(self))
# (adding some kind of salt may reduce the probability of
# hash collsions, but it works this way)
输出:
{MyTuple(a=1, b=2, c=3): 'my-tuple', (1, 2, 3): 'just-tuple'}
问题(S):
感谢您的努力。