2009-08-26 14 views
5

उदाहरण के लिए, मान लीजिए कि मैं यह कर:क्या यह एक पायथन कक्षा हैश के लिए एक अच्छा विचार है?

>>> class foo(object): 
...  pass 
... 
>>> class bar(foo): 
...  pass 
... 
>>> some_dict = { foo : 'foo', 
... bar : 'bar'} 
>>> 
>>> some_dict[bar] 
'bar' 
>>> some_dict[foo] 
'foo' 
>>> hash(bar) 
165007700 
>>> id(bar) 
165007700 

उस आधार पर, यह वर्ग की तरह अपने आईडी नंबर के रूप में टुकड़ों में बांटा जा रहा है लग रहा है। इसलिए, bar हैशिंग को foo या bar या हैश मान बदलते हैं, तो मैं कक्षा को बदलता हूं, इसके बारे में चिंता करने का कोई खतरा नहीं होना चाहिए।

क्या यह व्यवहार विश्वसनीय है, या यहां कोई गठिया है?

उत्तर

8

हां, कोई भी ऑब्जेक्ट जो __hash__() फ़ंक्शन को लागू नहीं करता है, उसके शेड होने पर उसकी आईडी वापस कर देगा। Python Language Reference: Data Model - Basic Customization से:

उपयोगकर्ता-परिभाषित वर्गों डिफ़ॉल्ट रूप से __cmp__() और __hash__() तरीकों है; उनके साथ, सभी वस्तुएं असमान की तुलना करती हैं (स्वयं को छोड़कर) और x.__hash__()id(x) लौटाती है।

हालांकि, यदि आप एक अद्वितीय पहचानकर्ता की तलाश में हैं, तो अपने इरादे के बारे में स्पष्ट होने के लिए id का उपयोग करें। किसी ऑब्जेक्ट का हैश इसके घटकों के हैंश का संयोजन होना चाहिए। अधिक जानकारी के लिए उपरोक्त लिंक देखें।

+2

कोई भी वर्ग जिसका * मेटाक्लास * में __hash __() फ़ंक्शन नहीं है। –

+0

यह ध्यान दिया जाना चाहिए कि हालांकि यह "पायथन 2.6 के लिए नया क्या है" पृष्ठ में है, यह व्यवहार मेरे लिए अजगर 2.4 के तहत काम करता प्रतीत होता है। –

+1

@ जेसन I ने सामान्य दस्तावेज के संदर्भ को बदल दिया। –

6

कक्षाओं में __eq__ और __hash__ का डिफ़ॉल्ट कार्यान्वयन है जो तुलना करने और क्रमशः हैश मानों की गणना करने के लिए id() का उपयोग करता है। यही है, वे पहचान से तुलना करते हैं। __hash__ विधियों को लागू करने के लिए प्राथमिक नियम यह है कि यदि दो वस्तुएं एक-दूसरे के बराबर होती हैं, तो उनके पास एक ही हैश मान भी होना चाहिए। हैश मानों को केवल डिक्ट्स द्वारा उपयोग किए जाने वाले ऑप्टिमाइज़ेशन के रूप में देखा जा सकता है और समान वस्तुओं को तेज़ी से ढूंढने के लिए सेट किया जा सकता है। नतीजतन, यदि आप एक अलग तरह के समानता परीक्षण करने के लिए __eq__ बदलते हैं, तो आपको उस विकल्प से सहमत होने के लिए अपना __hash__ कार्यान्वयन भी बदलना होगा।

कक्षाएं जो तुलना के लिए पहचान का उपयोग करती हैं उन्हें स्वतंत्र रूप से उत्परिवर्तित किया जा सकता है और डिक्ट्स और सेट में उपयोग किया जा सकता है क्योंकि उनकी पहचान कभी नहीं बदली जाती है। कक्षाओं की तुलना करने के लिए __eq__ लागू करने वाले वर्ग और उनके मूल्यों के उत्परिवर्तन की अनुमति हैश संग्रह में उपयोग नहीं किया जा सकता है।

संबंधित मुद्दे