2016-11-25 5 views
2

ハッシュ可能にしようとしているクラスを定義しました。さらに、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がより奇妙に見えます。

答えて

2

Enumクラスはメンバーオブジェクトの値を比較して、anyが別のものの別名であるかどうかを確認しています。たとえば、次の列挙型で、abの両方が(別名がない)ので、唯一のaがメンバーリストに表示されるはずです、同じ値を表す:

class A(Enum): 
    a=1 
    b=1 

あなたがソースを見て、これを確認することができます等価チェックを行った行のコード:source

ハッシュの場合、これは列挙型メンバーの値の検索を行うために行われます。繰り返しますが、source code

+0

これはすべてに対応しています。ありがとう。したがって、列挙型メンバーの値は、ハッシュ可能ではないリストのように、変更可能なオブジェクトにすることはできません。 – Shobhit

+1

可能です。値がハッシュ可能でない場合、それはバイナリルックアップテーブルには含まれないので、値で検索しようとすると、メンバーをループし、代わりに等価をチェックします – 3Doubloons

関連する問題