2013-11-01 9 views
5

मै जादू तुलना विधियों के कुछ भ्रमित व्यवहार में भाग गया हूं। मान लीजिए कि हमें निम्नलिखित वर्ग है:पायथन जादू विधि भ्रम

class MutNum(object): 
    def __init__ (self, val): 
     self.val = val 

    def setVal(self, newval): 
     self.val = newval 

    def __str__(self): 
     return str(self.val) 

    def __repr__(self): 
     return str(self.val) 

    # methods for comparison with a regular int or float: 
    def __eq__(self, other): 
     return self.val == other 

    def __gt__(self, other): 
     return self.val > other 

    def __lt__(self, other): 
     return self.val < other 

    def __ge__(self, other): 
     return self.__gt__(other) or self.__eq__(other) 

    def __le__(self, other): 
     return self.__lt__(other) or self.__eq__(other) 

वर्ग क्या यह एक नियमित पूर्णांक या नाव के लिए एक MutNum वस्तु की तुलना करने के लिए माना जाता है, करता है कोई समस्या नहीं है। हालांकि, और यही वह है जो मुझे समझ में नहीं आता है, यह जादू की विधियों को दो MutNum ऑब्जेक्ट्स दिए जाने पर ठीक से तुलना करता है।

a = MutNum(42) 
b = MutNum(3) 
print(a > b) # True 
print(a >= b) # True 
print(a < b) # False 
print(a <= b) # False 
print(a == b) # False 

यह क्यों काम करता है? धन्यवाद।

+1

उदाहरण के लिए, '__add__' और' __radd__' के समान संबंध में खड़े '__gt__' और' __lt__' के बारे में सोचने में मदद मिल सकती है। यदि पहला लागू नहीं होता है, तो पाइथन दूसरे को ऑपरेटरों के साथ कोशिश करता है। – chepner

उत्तर

4

यह इस प्रकार है (एक repr तरह अंकन का उपयोग करने के बजाय चर के संदर्भ में) का मूल्यांकन करता है:

MutNum(42) > MutNum(3) 
=> MutNum(42).__gt__(MutNum(3)) 
=> MutNum(42).val > MutNum(3) 
=> 42 > MutNum(3) 

और वहाँ से, यह सिर्फ पूर्णांक-MutNum तुलना आप पहले से ही काम करता है पता है।

+0

@ डस्ट * आप * ने कहा कि इस कक्षा के उदाहरणों के लिए नियमित स्याही और फ्लोट की तुलना करना कोई समस्या नहीं है ;-) '42> ... '' MutNum .__ gt__'' को फिर से नहीं बुलाएगा 42 के रूप में 'MutNum' नहीं है। इस प्रकार का भ्रम '__repr__' को परिभाषित करने का एक कारण नहीं है, लेकिन आपके पास कुछ ऐसा है जो distinguihes' Mutnum की संख्या को लपेटता है। – delnan

2

यदि आप कुछ प्रिंट और/या sys.stderr.write में फेंकते हैं, तो मुझे लगता है कि आप देखेंगे कि क्या हो रहा है। ईजी:

def __gt__(self, other): 
    sys.stderr.write('__gt__\n') 
    sys.stderr.write('{}\n'.format(type(other))) 
    sys.stderr.write('{} {}\n'.format(self.val, other)) 
    result = self.val > other 
    sys.stderr.write('result {}\n'.format(result)) 
    return result 

def __lt__(self, other): 
    sys.stderr.write('__lt__\n') 
    sys.stderr.write('{}\n'.format(type(other))) 
    sys.stderr.write('{} {}\n'.format(self.val, other)) 
    result = self.val < other 
    sys.stderr.write('result {}\n'.format(result)) 
    return result 

जब आप अन्य (एक MutNum) को self.val (किसी पूर्णांक) की तुलना करने की कोशिश, अजगर का एहसास है यह एक MutNum के लिए एक पूर्णांक की तुलना के लिए कुछ भी नहीं है, और तुलना के आदेश को उलट देता है, और एक Mutnum की तुलना int से करता है - जो कुछ आपने परिभाषित किया है। यही है, एक तुलना> तुलना कर रही है> जैसा कि आप उम्मीद करेंगे, लेकिन यह < भी कर रहा है।

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