ハッシュ可能にしようとしているクラスを定義しました。さらに、enumメンバーの値としてこのクラスのオブジェクトを使用するenumがあります。ハッシュ可能なクラスとPythonのEnumとの相互作用
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__
魔法のメソッドが2つの列挙メンバー値のために呼び出されること。なぜこれはそうですか?これらはハッシュと平等チェックの間だけ使われないのですか?
さらに、私がenumクラスを次のように変更すると、すべての地獄が緩んでしまいます。
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__
がクラスオブジェクトとリストを呼び出す理由は何ですか?
これは代表的な例に過ぎないことに注意してください。実際の使用事例では、ハッシュ可能なクラスオブジェクトのリストとして値を持つenumがより奇妙に見えます。
これはすべてに対応しています。ありがとう。したがって、列挙型メンバーの値は、ハッシュ可能ではないリストのように、変更可能なオブジェクトにすることはできません。 – Shobhit
可能です。値がハッシュ可能でない場合、それはバイナリルックアップテーブルには含まれないので、値で検索しようとすると、メンバーをループし、代わりに等価をチェックします – 3Doubloons