【发布时间】:2017-04-09 23:05:39
【问题描述】:
我已经定义了一个类,我正在尝试使其可散列。此外,还有一个枚举,它使用此类的对象作为其枚举成员的值。
from enum import Enum
class Dummy(object):
def __init__(self, name, property_):
self.name = name # can only be a string
self.property = property_ # can only be a string
def __hash__(self):
# print "Hash called for ", self
# print("----")
return hash(self.property)
def __eq__(self, other):
# print "Eq called for: "
# print self
# print other
return (self.property == other.property)
def __ne__ (self, other):
return not (self == other)
def __str__(self):
return (self.name + "$" + self.property)
class Property(Enum):
cool = Dummy("foo", "cool")
hot = Dummy("bar", "hot")
虽然这很好用,但我注意到 - 通过取消注释 print 语句 - 为两个枚举成员值调用了 __hash__ 和 __eq__ 魔术方法。为什么会这样?这些不是仅在哈希和相等检查期间使用吗?
此外,如果我将枚举类更改为以下内容,那么一切都会崩溃。
class Property(Enum):
cool = Dummy("foo", "cool")
hot = [Dummy("bar-1", "hot-1"), Dummy("bar-2", "hot-2")]
__eq__ 魔术方法似乎是为对应于Property.cool 的Dummy 对象和对应于Property.hot 的列表调用的,从输出中可以看出:
Hash called for foo$cool
----
Eq called for:
foo$cool
[<__main__.Dummy object at 0x7fd36633f2d0>, <__main__.Dummy object at 0x7fd36633f310>]
----
Traceback (most recent call last):
File "test.py", line 28, in <module>
class Property(Enum):
File "/blah/.local/lib/python2.7/site-packages/enum/__init__.py", line 237, in __new__
if canonical_member.value == enum_member._value_:
File "test.py", line 19, in __eq__
return (self.property is other.property)
AttributeError: 'list' object has no attribute 'property'
为什么会这样?为什么首先调用魔术方法,为什么在类对象和列表上调用__eq__?
请注意,这只是一个代表性示例,真实的用例使这种设计——将值作为可散列类对象列表的枚举——显得不那么奇怪。
【问题讨论】:
标签: python python-2.7 hash enums magic-methods