2016-11-25 1 views
2

해시 가능으로 만들려는 클래스를 정의했습니다. 또한이 클래스의 객체를 열거 형 멤버의 값으로 사용하는 열거 형이 있습니다. 이 잘 작동하지만해시 가능 클래스와 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__ 마법 방법은 두 가지 열거 멤버 값에 대해 호출됩니다. 이게 왜 그렇게? 해싱 및 평등 검사 중에 만 사용되지 않습니까?

또한 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__이 클래스 개체와 목록에서 호출되는 이유는 무엇입니까?

이것은 대표적인 예일 뿐이며 실제 사용 사례는이 디자인을 해시 가능한 클래스 개체의 목록으로 사용하는 열거 형이 덜 이상하게 보임을 유의하십시오.

답변

2

Enum 클래스는 구성원 개체 값을 비교하여 any가 다른 개체의 별칭인지 확인합니다. 예를 들어, 다음 열거에서 모두 ab 그렇게 만 a가 멤버 목록에 표시해야한다, 같은 값을 나타내는 (별칭은하지 않습니다) :

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

당신은 소스를 보면이를 확인할 수 있습니다 동등 검사를 한 행의 코드 : source

해시의 경우 열거 형 멤버를 기준으로 값 조회를 제공하기 위해 수행됩니다. 다시, 이것은에서 찾을 수 있습니다 source code

+0

이것은 모든 답변; 감사. 따라서 열거 형 멤버의 값은 해시 가능하지 않은 목록과 같이 변경 가능한 개체가 될 수 없습니다. – Shobhit

+1

그럴 수 있습니다. 값이 해시 가능하지 않으면 값 별 조회 테이블에만 포함되지 않으므로 값으로 찾으려면 멤버를 반복하고 대신 동등성을 확인하십시오. – 3Doubloons