2014-06-23 16 views
47

पहला परिणाम False क्यों है, क्या यह True नहीं होना चाहिए?ऑपरेटर 'है' के साथ अजीब व्यवहार

>>> from collections import OrderedDict 
>>> OrderedDict.__repr__ is OrderedDict.__repr__ 
False 
>>> dict.__repr__ is dict.__repr__ 
True 
+1

पायथन 3.3 सही – HashSplat

+0

देता है यह पायथन 2.7 है। – Chameleon

+1

@ जस्टिनएंजेल: ऐसा इसलिए है क्योंकि पायथन 3 अनबाउंड विधियों से दूर है, सभी विधियां बाध्य हैं। 'ऑर्डरर्ड डिक्ट() .__ repr__ को ऑर्डरर्ड डिक्ट() .__ repr__' पाइथन 3 में आज़माएं और आपको वही व्यवहार दिखाई देगा। –

उत्तर

56

उपयोगकर्ता परिभाषित कार्यों के लिए, अजगर 2 में अनबाउंड और बाध्य तरीकों descriptor protocol के माध्यम से, मांग पर बनाई गई हैं; OrderedDict.__repr__ ऐसी विधि वस्तु है, क्योंकि लपेटा गया फ़ंक्शन pure-Python function के रूप में कार्यान्वित किया गया है।

वर्णनकर्ता प्रोटोकॉल __get__ method को उन ऑब्जेक्ट्स पर कॉल करेगा जो इसका समर्थन करते हैं, इसलिए __repr__.__get__() को जब भी आप OrderedDict.__repr__ तक पहुंचने का प्रयास करते हैं तो कॉल किया जाता है; कक्षाओं के लिए None (कोई उदाहरण नहीं) और क्लास ऑब्जेक्ट स्वयं ही पास हो गया है। क्योंकि आपको नया विधि ऑब्जेक्ट मिलता है जब प्रत्येक बार फ़ंक्शन __get__ विधि लागू होती है, is विफल हो जाती है। यह एक ही विधि वस्तु नहीं है।

dict.__repr__ एक कस्टम पायथन फ़ंक्शन नहीं है लेकिन एक सी फ़ंक्शन नहीं है, और इसकी __get__ डिस्क्रिप्टर विधि essentially just returns self when accessed on the class है। विशेषता को एक्सेस करना आप एक ही वस्तु हर बार देता है, तो is काम करता है:

>>> dict.__repr__.__get__(None, dict) is dict.__repr__ # None means no instance 
True 

तरीके एक __func__ विशेषता लिपटे समारोह को संदर्भित है, का उपयोग करें कि पहचान के लिए परीक्षण करने के लिए:

>>> OrderedDict.__repr__ 
<unbound method OrderedDict.__repr__> 
>>> OrderedDict.__repr__.__func__ 
<function __repr__ at 0x102c2f1b8> 
>>> OrderedDict.__repr__.__func__.__get__(None, OrderedDict) 
<unbound method OrderedDict.__repr__> 
>>> OrderedDict.__repr__.__func__ is OrderedDict.__repr__.__func__ 
True 

अजगर 3 दूर करता है अनबाउंड विधियों के साथ, function.__get__(None, classobj) फ़ंक्शन ऑब्जेक्ट को स्वयं लौटाता है (इसलिए यह dict.__repr__ करता है)। लेकिन आप बाध्य विधियों के साथ एक ही व्यवहार देखेंगे, उदाहरण से पुनर्प्राप्त विधियों।

+1

अपने लिए यह साबित करने के लिए एक सरल परीक्षण के रूप में, अपनी '' __repr__' विधि 'के साथ एक वर्ग बनाएं, __repr__ = lambda: x'', और '' ''' परीक्षण विफल हो जाएगा। असल में, '' __repr__'' सामान्य रूप से ओवरराइड करने से '' '' विफल हो जाएगा। – aruisdante

+0

और, सामान्य मामले में, कोई कक्षा 'शुद्ध-पायथन अनबाउंड विधियां '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' के साथ '' True'' के रूप में तुलना करती हैं – aruisdante

+0

@aruisdante: ठीक है, आप विधि ऑब्जेक्ट का संदर्भ (एक से अधिक) बना सकते हैं, और फिर भी आप 'is' का उपयोग कर सकते हैं। लेकिन कक्षा से एक विधि को पुनर्प्राप्त करने से आपको एक नई वस्तु मिलती है क्योंकि फ़ंक्शन '__get__' विधि एक नई वस्तु उत्पन्न करती है। –

1

दो OrderedDict.__repr__ एक ही वस्तु के लिए बाध्य नहीं कर रहे हैं। यदि आप कोशिश करते हैं:

OrderedDict.__repr__ == OrderedDict.__repr__ 

आप देखेंगे कि उनके पास एक ही मूल्य है।

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