2010-09-24 11 views
10

.__hash__() 구현을 실행하는 데 시간이 오래 걸리는 클래스를 작성했습니다. 해시를 캐싱하려고 생각하고 ._hash과 같은 변수에 저장하므로 .__hash__() 메서드는 단순히 ._hash을 반환합니다. (.__init__() 끝나 또는 .__hash__()이 처음 호출 될 때 계산됩니다.)파이썬 : 객체의 해시를 캐시하지 않는 이유가 있습니까?

추론은 다음과 같습니다. "이 개체는 불변입니다. - 해시가 변경되지 않습니다."> 해시를 캐시 할 수 있습니다. "

하지만 이제는 내게 생각이 들었다. 에 대해 같은 말을 할 수있다. 해시 가능 객체. (해시가 ID 인 객체를 제외하고)

이 아닌은 해시 계산이 매우 빠른 작은 객체를 제외하고 객체의 해시를 캐시 할 수 있습니까?

답변

8

물론 해시 값을 캐시하는 것이 좋습니다. 실제로 파이썬은 문자열 자체에 대해 그렇게합니다. 트레이드 오프는 해시 계산 속도와 해시 값을 저장하는 데 필요한 공간 사이에 있습니다. 그 트레이드 오프는 예를 들어 튜플이 해시 값을 캐시하지 않는 이유이며 문자열은 않습니다 (request for enhancement #1462796 참조).

0

일반적인 이유는 파이썬의 대부분의 객체가 변경 가능하기 때문입니다. 따라서 해시가 속성에 따라 다르면 속성을 변경하자마자 변경됩니다. 당신의 클래스가 정말로 불변이고 (해쉬에 들어가는 모든 프로퍼티도 변경할 수 없다면) 해쉬를 캐시 할 수 있습니다.

+5

물론 개체가 변경 가능하다면, 일반적으로 '__hash__'을 구현하는 것은 좋지 않습니다. '__hash__ '의 유일한 내장 된 사용은 해시가 안정적 일 것을 요구합니다. –

+2

아니요,'__hash__'의 기본 구현은 객체의 속성을 변경할 때 다른 것을 반환하지 않습니다. 기본적으로 이는 모든 객체에 대해 true입니다. 'hash (obj) == id (obj) == hash (id (obj))'- 객체가 ID를 해시로 사용한다는 것을 의미합니다. id는 정적이므로 개체가 기본적으로 해시를 "캐시"한다고 말할 수 있습니다. –

관련 문제