2016-07-18 8 views
5
class Inner(): 

    def __init__(self, x): 
     self.x = x 

    def __eq__(self, other): 
     if isinstance(other, Inner): 
      return self.x == other.x 
     else: 
      raise TypeError("Incorrect type to compare") 

class Outer(): 

    def __init__(self, y): 
     self.y = Inner(y) 

    def __eq__(self, other): 
     if isinstance(other, Outer): 
      return self.y == other.y 
     elif isinstance(other, Inner): 
      return self.y == other 
     else: 
      raise TypeError("Incorrect type to compare") 


if __name__ == "__main__": 

    a = Outer(1) 
    b = Inner(1) 

    print(a == b) # ok no problem 
    print(b == a) # This will raise a type error 

उदाहरण में मेरे अंदर और बाहरी वर्ग में 'उलट' तुलना ऑपरेटर। मेरे पास कोई नियंत्रण नहीं है कि आंतरिक उपकरण केवल स्थिति को अनुकरण करना चाहते थे। मेरे पास केवल बाहरी व्यवहार पर नियंत्रण है। मैं बाहरी उदाहरणों को आंतरिक उदाहरणों की तुलना करने में सक्षम होना चाहता हूं (केवल समानता नहीं)। दिए गए कार्यान्वयन के साथ केवल पहली तुलना काम करती है क्योंकि वह बाहरी और आंतरिक उदाहरणों की तुलना में ऑउटर की __eq__ विधि को कॉल करने की अनुमति दे रही है लेकिन दूसरा व्यक्ति इनर के __eq__ को कॉल कर रहा है जो बाहरी से तुलना करने की अनुमति नहीं देगा - बिल्ली यह नहीं जानता कि बाहरी मौजूद है इसे लागू करने के लिए परेशान क्यों होना चाहिए। क्या __radd__ और ऐसे कार्यों जैसे कुछ काम के साथ काम की दूसरी प्रकार की तुलना करने का कोई तरीका है। मुझे उदाहरण के लिए सी ++ में पता है, आप इनलाइन ऑपरेटर परिभाषाओं के साथ इसे हल करते हैं, लेकिन हमारे पास पाइथन में ऐसा नहीं है।पाइथन

उत्तर

2

इस पर एक बहुत अच्छा बिंदु नहीं डालना: Inner.__eq__ टूट गया है। कम से कम, बल्कि एक त्रुटि यह होना चाहिए return NotImplemented, जो अजगर रिवर्स तुलना की कोशिश करने की अनुमति होगी फेंकने से:

जब NotImplemented दिया जाता है, दुभाषिया तो कोशिश करेंगे अन्य प्रकार पर आपरेशन परिलक्षित होता है, या ऑपरेटर के आधार पर कुछ अन्य फ़ॉलबैक, । यदि सभी प्रयास किए गए ऑपरेशन NotImplemented लौटाते हैं, तो दुभाषिया एक उचित अपवाद उठाएगा।

अभी तक बेहतर यह "duck typing" का प्रयोग करेंगे, बल्कि एक विशिष्ट वर्ग पर जोर (जब तक कि वर्ग, बल्कि इसके इंटरफेस से, तुलना का एक स्पष्ट रूप से महत्वपूर्ण हिस्सा है) की तुलना में:

def __eq__(self, other): 
    try: 
     return self.x == other.x 
    except AttributeError: 
     return NotImplemented 

हालांकि, जैसा कि आप कहते हैं कि आप इसे नियंत्रित नहीं कर सकते हैं, आपको मैन्युअल रूप से समान कार्यक्षमता को कार्यान्वित करना होगा, उदाहरण के लिए:

def compare(a, b): 
    """'Safe' comparison between two objects.""" 
    try: 
     return a == b 
    except TypeError: 
     return b == a 

Python's data model में __req__ जैसी कोई चीज़ नहीं है।