2013-03-18 6 views
5

हालांकि शीर्षक को तीन प्रश्नों के रूप में व्याख्या किया जा सकता है, वास्तविक समस्या का वर्णन करना सरल है। एक लिनक्स सिस्टम पर मेरे पास अजगर 2.7.3 स्थापित है, और पाइथन 3 असंगतताओं के बारे में चेतावनी देना चाहता हूं। इसलिए, मेरा कोड स्निपेट (tester.py) लगता है कि:समानता ऑपरेटर के लिए एक पायथन 3 बहिष्करण चेतावनी को कैसे खत्म करें?

#!/usr/bin/python -3 

class MyClass(object):  
    def __eq__(self, other): 
     return False 

जब मैं इस कोड स्निपेट को अंजाम

के रूप में (केवल एक समस्या है, न कि कोड का एक वास्तविक टुकड़ा दिखाने के लिए मैं अपने प्रोजेक्ट में उपयोग कर रहा हूँ माना)

./tester.py:3: DeprecationWarning: Overriding __eq__ blocks inheritance of __hash__ in 3.x 
    class MyClass(object): 

मेरा प्रश्न: मैं इस कोड स्निपेट कैसे बदल सकता हूँ, चेतावनी से छुटकारा पाने के यानी यह संस्करण के लिए संगत बनाने के लिए

./tester.py 

मैं निम्नलिखित प्रतिवाद चेतावनी मिलती है 3? मैं समानता ऑपरेटर को सही तरीके से कार्यान्वित करना चाहता हूं, न केवल चेतावनी या कुछ इसी तरह दबा रहा हूं।

+0

'' __eq__' object' से विरासत में मिली वस्तुओं के लिए झूठी वापस आ जाएगी जब तक कि 'एक बस एक डमी हैश समारोह अनिवार्य रूप से लौटने nonesense A' – thkang

उत्तर

5

अजगर 3.4 के लिए documentation पृष्ठ से:

एक वर्ग एक __eq__() विधि यह या तो एक __hash__() आपरेशन को परिभाषित नहीं किया जाना चाहिए परिभाषित नहीं करता है; यदि यह __eq__() को परिभाषित करता है लेकिन __hash__() नहीं है, तो इसके उदाहरण हैशबल संग्रह में आइटम के रूप में उपयोग योग्य नहीं होंगे। यदि कोई वर्ग म्यूटेबल ऑब्जेक्ट्स को परिभाषित करता है और __eq__() विधि लागू करता है, तो इसे __hash__() लागू नहीं करना चाहिए, क्योंकि हैशबल संग्रह के कार्यान्वयन के लिए आवश्यक है कि एक कुंजी हैश मान अपरिवर्तनीय है (यदि ऑब्जेक्ट का हैश मान बदलता है, तो यह गलत हैश बाल्टी में होगा)।

असल में, आपको __hash()__ फ़ंक्शन को परिभाषित करने की आवश्यकता है।

समस्या यह है कि उपयोगकर्ता द्वारा परिभाषित कक्षाओं के लिए, __eq()__ और __hash()__ फ़ंक्शंस स्वचालित रूप से परिभाषित किए जाते हैं।

x.__hash__() एक उपयुक्त मान देता है ऐसा है कि x == y तात्पर्य दोनों कि x is y और hash(x) == hash(y)

तुम सिर्फ __eq()__ निर्धारित करते हैं तो __hash()__None वापस जाने के लिए निर्धारित है। तो आप दीवार हिट करेंगे।

यदि आप __hash()__ को लागू करने के बारे में परेशान नहीं करना चाहते हैं तो सरल तरीका यह है कि आप निश्चित रूप से जानते हैं कि आपकी वस्तु कभी नहीं छोड़ी जाएगी, आप स्पष्ट रूप से __hash__ = None घोषित करते हैं जो चेतावनी का ख्याल रखता है।

+0

है? या एक ऐसा फ़ंक्शन जो वास्तव में उपयोग करने योग्य हैश मान देता है? लेकिन मुझे ऐसा करने की ज़रूरत क्यों नहीं है, यह दस्तावेज स्निपेट से स्पष्ट नहीं है। – Alex

+0

फिर से, उसी पृष्ठ से: '__hash __() 'को एक पूर्णांक वापस करना चाहिए। एकमात्र आवश्यक संपत्ति यह है कि समान वस्तुओं की तुलना में समान हैश मान –

+0

हैश और eq फ़ंक्शंस के बारे में विवरण पढ़ें - वे इसे स्पष्ट करते हैं। –

0

एलेक्स: पायथन -3 विकल्प आपको संभावित समस्या के बारे में चेतावनी दे रहा है; यह नहीं जानता कि आप सेट में MyClass के उदाहरण या मैपिंग में कुंजी के रूप में उपयोग नहीं कर रहे हैं, इसलिए यह चेतावनी देता है कि आप जिस पर भरोसा कर रहे थे, वह काम नहीं करेगा, अगर आप थे। यदि आप MyClass का उपयोग इस तरह से नहीं कर रहे हैं, तो केवल चेतावनी को अनदेखा करें। संभावित समस्याओं को पकड़ने में आपकी सहायता के लिए यह एक गूंगा उपकरण है; अंत में, आपको वास्तविक बुद्धि के साथ एक होने की उम्मीद है कि वास्तव में कौन सी चेतावनियां वास्तव में मायने रखती हैं।

तुम सच में चेतावनी को दबा के बारे में परवाह है - या, वास्तव में, अगर एक वर्ग परिवर्तनशील है और आप यकीन है कि यह नहीं सेटों में या किसी मानचित्रण में कुंजी के रूप में प्रयोग किया जाता है बनाना चाहते - सरल काम __hash__ = None (जैसा कि सुदीपता ने बताया) कक्षा के शरीर में यह आपके लिए किया जाएगा। चूंकि कोई भी कॉल करने योग्य नहीं है, इसलिए यह उदाहरण गैर-हानिकारक बनाता है।

class MyClass (object): 
     def __eq__(self, other): return self is other 
     __hash__ = None 
संबंधित मुद्दे