2012-11-21 18 views
6

मैं तारों के लिए एक कस्टम हैशिंग फ़ंक्शन बनाने की कोशिश कर रहा हूं। मैं वजन से अपने चरित्र आवृत्ति द्वारा हैश तार करना चाहता हूँ। तो hi और ih एक ही हैश उत्पन्न करेगा। क्या मैं __hash__ ओवरराइड कर सकता हूं?पायथन ओवरराइडिंग स्ट्रिंग __hash__

या एक रैपर वर्ग बना रहा है जो स्ट्रिंग और ओवरराइडिंग __hash__ और __eq__ एकमात्र तरीका है?

+0

मैं रैपर वर्ग का उपयोग करूंगा। यह अच्छा और स्पष्ट है और एक स्ट्रिंग होने का नाटक करके भ्रम पैदा नहीं करेगा, फिर भी पूरी तरह से अलग हैशिंग। – millimoose

+0

@millimoose अच्छी बात – darksky

+1

हैश के रूप में हैश का उपयोग करने वाले कंटेनर में 'str' और' custom_str' मिक्स करना दिलचस्प हो सकता है :) –

उत्तर

4

आप एक समान प्रकार के समान समानता अर्थशास्त्र के साथ व्युत्पन्न प्रकार चाहते हैं। आम तौर पर लिया गया दृष्टिकोण यह निर्धारित करना होगा कि समानता कैसे काम करती है, फिर वहां व्युत्पन्न संरचनाओं से हैश विधि का निर्माण करें, क्योंकि यह उत्थान है कि हैश समानता से सहमत है। यह हो सकता है:

import collections 

class FrequencyString(str): 
    @property 
    def normalized(self): 
     try: 
      return self._normalized 
     except AttributeError: 
      self._normalized = normalized = ''.join(sorted(collections.Counter(self).elements())) 
      return normalized 

    def __eq__(self, other): 
     return self.normalized == other.normalized 

    def __hash__(self): 
     return hash(self.normalized) 
+1

मान लें कि मैं एक नि: शुल्क फ़ंक्शन बनाता हूं जो एक हैश वापस कर देगा। मैं वापस की हैश स्थिति पर उस कुंजी को कैसे सम्मिलित करूं? क्या 'dict = {}, dict [5] = value' insert' value' स्थिति 5 पर, या कुंजी '5' पर है? – darksky

+0

डिक्ट्स में मान रखकर * करता है * समानता अर्थात् बदलती है, यह ऐसा करने का सही तरीका है। आप वैकल्पिक रूप से रैपर को एक लिफाफे के रूप में संरचना कर सकते हैं, जिसमें मूल स्ट्रिंग एक उदाहरण विशेषता के रूप में है। – SingleNegationElimination

0

आपकी धारणा सही है, आप पायथन में बेस क्लासेस को ओवरराइड नहीं कर सकते हैं। हालांकि, निश्चित रूप से, str() क्या ओवरराइड कर सकता है, यह स्ट्रिंग अक्षर के लिए काम नहीं करेगा।

आप UserString वर्ग में पूर्व अजगर 2.2 देखने के लिए कोड लिखने रहे हैं, तो आप बनाना चाहते हैं, तो अपनी खुद की: http://docs.python.org/2/library/userdict.html#module-UserString

अन्यथा आप बस उसे str या unicode

आपके मामले में वारिस कर सकते हैं बस अधिलेखन __hash__ विधि पर्याप्त है यदि आप इसे एक dict कुंजी के रूप में उपयोग करना चाहते हैं। लेकिन आप तुलना देख रहे हैं क्या आप अधिलेखित करना __eq__ या __cmp__

+0

Argghghh - नहीं, 'UserString' के लिए नहीं, नहीं - यह प्राचीन इतिहास है -' वर्ग 'जैसे' वर्ग 'से प्राप्त होता है जैसे' वर्ग mystr (str): ... ' –

+0

यह कहता है कि मुझे संस्करणों के लिए पिछड़े संगतता का समर्थन करने की आवश्यकता नहीं है 2.2 से पहले, मैं केवल 'str' में निर्मित से सीधे subclass कर सकते हैं। यह कैसे किया जाएगा? क्या यह बस होगा: 'वर्ग wrapper_class (str): '? क्या '__hash__' और' __eq__' को ओवरराइड करना पर्याप्त होगा? – darksky

+0

@ जोनमेंट्स आपने अभी मेरी टिप्पणी के भाग 1 का उत्तर दिया :) विधियों के ओवरराइड के बारे में क्या? '__hash__' और' __eq__' पर्याप्त होगा? – darksky

0

आप str से विरासत सकता है, लेकिन जब से उन अपरिवर्तनीय हैं कि आप उन्हें एक से थोड़ा अलग तरह से उपवर्ग के लिए है की तुलना में। सबसे अधिक संभावना है कि आप मौजूदा तारों से नए बनाना चाहते हैं, इसलिए आपको __new__ विधि को ओवरराइड करना होगा। पाइथन द्वारा किए गए अनुकूलन को हराने के लिए आपको अतिरिक्त विशेष तरीकों को भी शामिल करना पड़ सकता है।

अंतर्निहित str, mapstr ऑब्जेक्ट उप-वर्गीकरण का उदाहरण है जो आसानी से प्रतिस्थापन प्लेसहोल्डर को रूपों में अनुमति देता है।

+0

क्या आप समझ सकते हैं कि "क्या आप मौजूदा तारों से नए बनाना चाहते हैं" से आपका क्या मतलब है? मैं बस एक स्ट्रिंग बनाना चाहता हूं जिसे मैं '__init__' में पास कर सकता हूं, तो मुझे' __new__' उपclass क्यों करना होगा? अगर मैं नहीं करता तो क्या होता है? – darksky

+0

तो आप इसका उपयोग करने की योजना कैसे बनाते हैं? – Keith

+0

एक कुंजी में समान वर्ण रखने वाले तारों को धक्का देना। मान सभी तारों की एक सूची है। कुंजी उनमें से एक क्रमबद्ध संस्करण है। – darksky

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