2014-07-01 4 views
7

क्यों निम्नलिखित कोड काम ठीक पायथन 2.x में और नहीं पायथन में 3.3+ करता है:तर्क के साथ ऑब्जेक्ट .__ new__ क्यों Python 2.x में ठीक है और पायथन 3.3+ में नहीं है?

class TestA(object): 
    def __new__(cls, e): 
     return super(TestA, cls).__new__(TestB, e) 

class TestB(TestA): 
    def __init__(self, e): 
     print(self, e) 

TestA(1) 

अजगर 2.7.6 उत्पादन:

(<__main__.TestB object at 0x7f6303378ad0>, 1) 

अजगर 3.1.5 उत्पादन:

__main__:3: DeprecationWarning: object.__new__() takes no parameters 
<__main__.TestB object at 0x7f2f69db8f10> 1 

अजगर 3.2.3 और 3.2.5 उत्पादन:

<__main__.TestB object at 0xcda690> 1 

अजगर 3.3.5 और 3.4.1 उत्पादन:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in __new__ 
TypeError: object() takes no parameters 
+3

संबंधित: [ऑब्जेक्ट क्यों करता है। \ _ \ _ नया \ _ \ _ इन तीन मामलों में अलग-अलग काम करता है] (http://stackoverflow.com/q/19277399) –

+0

यह व्याख्याकर्ता आउटपुट, पहला प्रिंट, दूसरा ऑब्जेक्ट है। यदि कार्यक्रम के रूप में चलाया जाता है तो एक पंक्ति होगी। फिक्स्ड। – tbicr

+0

क्या आप निश्चित हैं? यह कोड पायथन 2.7.4 और पायथन 3.2.3 पर काम करता है। –

उत्तर

3

object.__new__ हमेशा अतिरिक्त तर्कों पर ध्यान नहीं दिया गया है, और कम से कम अजगर 2.6 के बाद से एक DeprecationWarning जारी किया है।

कारण आप 2.7 और 3.2 में DeprecationWarning नहीं देख रहे हैं, क्योंकि 2.7 और 3.2 DeprecationWarningsuppressed by default रहा है; यदि आप python -Wd या PYTHONWARNINGS=default का उपयोग करते हैं तो आपको चेतावनी दिखाई देगी।

पायथन 3.3 में DeprecationWarning को एक त्रुटि में परिवर्तित कर दिया गया था।

अपना कोड लिखना (अजगर के किसी भी संस्करण में) सही तरीका TestA.__new__ में अतिरिक्त तर्क निगल करने के लिए है:

class TestA(object): 
    def __new__(cls, e): 
     return super(TestA, cls).__new__(TestB) 

TestB के बाद से TestA से ली गई है, अतिरिक्त तर्क will be passed to TestB.__init__

0

तुम इतनी तरह टेस्टा को __init__ समारोह स्थानांतरित कर सकते हैं:

class TestA(object): 
    def __new__(cls, e): 
     return super(TestA, cls).__new__(TestA) 

    def __init__(self, e): 
     print(self, e) 

TestA(1) 

सूचना कैसे TestB आवश्यकता नहीं है।

ध्यान दें कि कॉल से ऑब्जेक्ट से 'ई' पैरामीटर कैसे छोड़ा जाता है .__ new__। ऑब्जेक्ट क्लास का नया फ़ंक्शन केवल क्लास के रूप में क्लास लेता है और अधिभारित __new__ फ़ंक्शन में किसी भी अतिरिक्त पैरामीटर (क्लास टेस्टा के इस मामले में) ऑब्जेक्ट को उत्तीर्ण वर्ग के कन्स्ट्रक्टर फ़ंक्शन (__init__) पर स्वचालित रूप से पास किया जाता है .__ new__ (जो इस मामले में भी टेस्टए है)।

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