2012-09-17 6 views
6

मैं निम्नलिखित कोड है: अगर मैं int का एक उपवर्ग बनानेऑपरेटर ओवरलोडिंग करते समय पाइथन कॉन्स प्रकार करता है?

a = str('5') 
b = int(5) 
a == b 
# False 

लेकिन, और __cmp__ reimplement:

class A(int): 
    def __cmp__(self, other): 
     return super(A, self).__cmp__(other) 
a = str('5') 
b = A(5) 
a == b 
# TypeError: A.__cmp__(x,y) requires y to be a 'A', not a 'str' 

क्यों इन दो अलग अलग कर रहे हैं? क्या पाइथन रनटाइम int.__cmp__() द्वारा फेंक टाइपर को पकड़ रहा है, और इसे False मान के रूप में व्याख्या कर रहा है? क्या कोई मुझे 2.x cpython स्रोत में थोड़ा सा इंगित कर सकता है जो दिखाता है कि यह कैसे काम कर रहा है?

+0

एक तरफ ध्यान दें: आप जानते हैं कि '__cmp__' उम्र पहले बहिष्कृत किया गया था? आपको समृद्ध-तुलनात्मक कार्यों को लागू करना चाहिए। – Bakuriu

+0

हां, यह तब आया जब मैं यह पता लगाने की कोशिश कर रहा था कि क्या मुझे अपवाद उठाना चाहिए या __eq__ के कार्यान्वयन में लागू नहीं किया जाना चाहिए। मैं देखना चाहता था कि बिल्टिन पायथन कक्षाओं ने क्या किया, और यह उदाहरण पाया जो असंगत लग रहा था। – Chris

उत्तर

5

प्रलेखन इस मुद्दे पर पूरी तरह से स्पष्ट नहीं है, लेकिन here देखें:

यदि दोनों नंबर, वे एक आम प्रकार में बदल दिए जाते रहे हैं। अन्यथा, विभिन्न प्रकार की वस्तुएं हमेशा असमान की तुलना करती हैं, और मनमाने ढंग से लेकिन मनमाने ढंग से आदेश दिया जाता है। आप __cmp__ विधि या __gt__ जैसे समृद्ध तुलना विधियों को परिभाषित करके गैर-निर्मित प्रकार की वस्तुओं की तुलनात्मक व्यवहार को नियंत्रित कर सकते हैं, अनुभाग विशेष विधि नामों में वर्णित है।

यह (विशेष रूप से "विभिन्न प्रकार की वस्तुओं" और के बीच निहित विपरीत "की वस्तुओं गैर निर्मित प्रकार") पता चलता है कि वास्तव में बुला तुलना तरीकों की सामान्य प्रक्रिया के लिए निर्मित प्रकार को छोड़ दिया जाता है: अगर आप दो अलग-अलग प्रकार (और गैर-संख्यात्मक) अंतर्निर्मित प्रकारों की वस्तुओं की तुलना करने का प्रयास करते हैं, यह स्वचालित झूठी को केवल शॉर्ट-सर्किट करता है।

-2

अगर मैं आपकी समस्या को सही समझ में आया, आप की तरह कुछ की जरूरत है:

>>> class A(int): 
...  def __cmp__(self, other): 
...   return super(A, self).__cmp__(A(other)) # <--- A(other) instead of other 
... 
>>> a = str('5') 
>>> b = A(5) 
>>> a == b 
True 

अपडेट किया गया

CPython स्रोत 2.x के लिए के बारे में, आप समारोह wrap_cmpfunc में typeobject.c में इस परिणाम के लिए कारण मिल सकता है जो वास्तव में दो चीजों की जांच करता है: दिए गए तुलना फ़ंक्शन func और otherself के लिए उप प्रकार है।

if (Py_TYPE(other)->tp_compare != func && 
    !PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self))) { 
// .... 
} 
+3

मुझे नहीं लगता कि यह इस सवाल को बिल्कुल संबोधित करता है। मुझे लगता है कि ओपी पहचानता है कि तुलनात्मक काम करने के लिए वह दूसरे के प्रकार को मजबूर कर सकता है। सवाल यह है कि उसे क्यों करना है? * '__cmp__' क्यों नहीं देखते हैं कि प्रकार समान नहीं हैं और तुरंत 'झूठी' वापस आते हैं? – mgilson

+4

प्रश्न यह है कि दो अलग-अलग परिणाम क्यों हैं, न कि 'str' और' int' की तुलना कैसे करें। –

+0

अद्यतन उत्तर। –

3

a == b के लिए एक तुलना निर्णय वृक्ष लगता है कि कुछ:

  • अजगर कॉल a.__cmp__(b)
    • a जांच करता है कि b एक उचित प्रकार
    • अगर b एक उचित प्रकार है, -1 लौटने के लिए, 0, या +1
    • यदि b है नहीं, वापसी NotImplented
  • अगर -1, 0, या +1 लौटे, अजगर किया जाता है; अन्यथा
  • अगर NotImplented लौटे,,
  • b.__cmp__(a)
    • b चेकों की कोशिश है कि a एक उचित प्रकार
    • अगर a एक उचित प्रकार है लौटने -1, 0, या +1
    • अगर a नहीं है, वापसी NotImplemented
  • यदि -1, 0, या +1 लौटा, पायथन किया जाता है; अन्यथा
  • अगर NotImplented फिर से लौट आए, इस सवाल का जवाब False

नहीं एक सटीक जवाब है, लेकिन उम्मीद है कि यह मदद करता है।

+0

अच्छा है, लेकिन त्रुटि संदेश की व्याख्या नहीं करता है। –

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