2010-09-21 3 views
8

में रिवर्स ऑपरेटरों का उपयोग करके मैंने पहले कभी रिवर्स ऑपरेटर को संभाला नहीं है, इसलिए कृपया कोई फ्लेमिंग नहीं करें! बस उनके बारे में सीखना समाप्त कर दिया ताकि वे उन्हें आजमा सकें। लेकिन किसी कारण से, यह काम नहीं कर रहा है।पायथन

>>> class Subtract(object): 
    def __init__(self, number): 
     self.number = number 
    def __rsub__(self, other): 
     return self.number - other.number 


>>> x = Subtract(5) 
>>> y = Subtract(10) 
>>> x - y   # FAILS! 

Traceback (most recent call last): 
    File "<pyshell#8>", line 1, in <module> 
    x - y 
TypeError: unsupported operand type(s) for -: 'Subtract' and 'Subtract' 
>>> x.__rsub__(y) # WORKS! 
-5 

अगर मैं बदल __rsub____sub__ करने के लिए, यह काम करता है: यहाँ कोड है।

मैं क्या गलत कर रहा हूं? इन रिवर्स ऑपरेटरों का उद्देश्य भी क्या है?

उत्तर

4

__rsub__() केवल तभी कॉल किया जाएगा जब ऑपरेंड विभिन्न प्रकार के होते हैं; जब वे एक ही प्रकार के होते हैं तो यह माना जाता है कि यदि __sub__ मौजूद नहीं है तो उन्हें घटाया नहीं जा सकता है।

यह भी ध्यान रखें कि आपके तर्क किसी भी मामले में उलट दिया गया है; अन्य के बजाय अन्य - - आप स्वयं के लिए लौट रहे स्व

+0

लेकिन स्पष्ट रूप से '__rsub__' को कॉल करने के तरीके कैसे आते हैं? – Randy

+0

क्योंकि '__rsub__' एक फ़ंक्शन है जिसे आपने परिभाषित किया है और आप इसे किसी अन्य फ़ंक्शन की तरह कॉल कर सकते हैं; यह केवल '-' ऑपरेटर को लागू करने के लिए स्वचालित रूप से नहीं बुलाया जाएगा। – geoffspear

+0

@ रैंडी: क्योंकि जब आप इसे स्पष्ट रूप से कहते हैं, तो यह केवल एक नियमित विधि है। आप उम्मीद क्यों करेंगे कि यह काम न करे? '__rsub__' के बारे में विशेष बात यह है कि कुछ परिस्थितियों में, पायथन एक घटाव ऑपरेशन ' - <__rsub__'' पर कॉल में <कुछ और> 'का अनुवाद करेगा - लेकिन उत्तर में समझाया गया है, उन निश्चित परिस्थितियों में मौजूद नहीं हैं आपका उदाहरण –

2

ताकि आपके वर्ग एक ऑपरेटर जब बाईं संकार्य एक आदिम या कुछ और जो आपके नियंत्रण में नहीं है लागू कर सकते हैं methods with reflected operands प्रदान की जाती हैं:

These functions are only called if the left operand does not support the corresponding operation and the operands are of different types.

चूंकि वे एक ही प्रकार के हैं, इसलिए यह डरावनी रूप से इनकार कर रहा है और आपको __sub__ विधि को लागू करना चाहिए।

3

पायथन के डाटा मॉडल से http://docs.python.org/reference/datamodel.html पर:

These methods are called to implement the binary arithmetic operations (+, -, *, /, %, divmod(), pow(), **, <<, >>, &, ^, |) with reflected (swapped) operands. These functions are only called if the left operand does not support the corresponding operation and the operands are of different types. [2] For instance, to evaluate the expression x - y, where y is an instance of a class that has an __rsub__() method, y.__rsub__(x) is called if x.__sub__(y) returns NotImplemented.

हालांकि - दोनों वस्तुओं एक ही कक्षा की नहीं होना चाहिए -, इसका मतलब है कि भले ही आप एक __sub__ विधि डाल अपने उदाहरण पर ऊपर NotImplemented लौटने के बाद आप करेंगे अभी भी वही त्रुटि मिलती है: पायथन बस मानता है कि आपकी घटिया कक्षा "घटाना" iobjects से घटा नहीं सकती है, चाहे कोई भी आदेश न हो।

बहरहाल, यह काम करता है:

class Sub1(object): 
    number = 5 
    def __sub__(self, other): 
     return NotImplemented 

class Sub2(object): 
    number = 2 
    def __rsub__(self, other): 
     return other.number - self.number 


a = Sub1() 
b = Sub2() 

print a - b 
3

इन तरीकों में से बिंदु पर इसकी अनुमति नहीं है: हालांकि

class MyNumber(object): 
    def __init__(self, x): 
     self.x = x 

print 10 - MyNumber(9) # fails because 10.__sub__(MyNumber(9)) is unknown 

class MyFixedNumber(MyNumber): 
    def __rsub__(self, other): 
     return MyNumber(other - self.x) 

print 10 - MyFixedNumber(9) # MyFixedNumber(9).__rsub__(10) is defined 

शायद ही कभी उपयोगी है, आमतौर पर आप सिर्फ एक ही प्रकार के और प्रत्यक्ष की चीजों का उपयोग __sub__