2009-10-14 14 views
43
साथ उपवर्गीकरण अजगर टपल

निम्नलिखित कोड काम करता है:कई __init__ तर्क

class Foo(tuple): 

    def __init__(self, b): 
     super(Foo, self).__init__(tuple(b)) 

if __name__ == '__main__': 
    print Foo([3, 4]) 

$ python play.py 
play.py:4: DeprecationWarning: object.__init__() takes no parameters 
    super(Foo, self).__init__(tuple(b)) 
(3, 4) 

लेकिन निम्नलिखित नहीं:

class Foo(tuple): 

    def __init__(self, a, b): 
     super(Foo, self).__init__(tuple(b)) 

if __name__ == '__main__': 
    print Foo(None, [3, 4]) 

$ python play.py 
Traceback (most recent call last): 
    File "play.py", line 7, in <module> 
    print Foo(None, [3, 4]) 
TypeError: tuple() takes at most 1 argument (2 given) 

क्यों?

उत्तर

55

क्योंकि tuples अपरिवर्तनीय हैं, आप के बजाय __new__ ओवरराइड करने के लिए है:

python docs

object.__new__(cls[, ...])

वर्ग cls का एक नया उदाहरण बनाने के लिए कहा जाता है। __new__() एक स्थिर विधि (विशेष-श्रेणीबद्ध है, इसलिए आपको इसे इस तरह घोषित करने की आवश्यकता नहीं है) जो कक्षा लेता है जिसमें से एक उदाहरण का पहला तर्क था। शेष तर्क वस्तु निर्माता अभिव्यक्ति (वर्ग के लिए कॉल) के लिए पारित कर दिया होते हैं। __new__() की वापसी मूल्य नई वस्तु दृष्टान्त (आमतौर पर एक उदाहरण cls की ) होना चाहिए।

विशिष्ट कार्यान्वयन सुपर क्लास के __new__() विधि लागू उचित तर्क के साथ super(currentclass, cls).__new__(cls[, ...]) और का उपयोग कर तो नव निर्मित उदाहरण को संशोधित करने के रूप में आवश्यक लौटने से पहले यह द्वारा वर्ग की एक नई उदाहरण पैदा करते हैं।

__new__() cls का एक उदाहरण देता है, तो उसके बाद नया उदाहरण के __init__() विधि __init__(self[, ...]), जहां स्वयं नया उदाहरण और शेष तर्क एक ही रूप में __new__() को पारित किए गए हैं जैसे सक्रिय किया जाएगा।

तो __new__()cls के उदाहरण वापस नहीं करता है, तो नए उदाहरण के __init__() विधि लागू किया जा नहीं होगा।

__new__() उदाहरण निर्माण अनुकूलित करने के लिए ( int, str, या tuple) की तरह अडिग प्रकार के उपवर्गों अनुमति देने के लिए मुख्य रूप से करना है। यह आमतौर पर वर्ग निर्माण अनुकूलित करने के लिए क्रम में कस्टम metaclasses में अधिरोहित है।

+0

क्या कोई मुझे बता सकता है कि पूरे ब्लॉक को कैसे उद्धृत किया जाए ताकि डबल अंडरस्कोर का मतलब बोल्ड न हो? –

+0

पूरे पेस्ट किए गए टेक्स्ट का चयन करें और उद्धरण चिह्न (टेक्स्ट बॉक्स के शीर्ष पर काला आइकन) पर क्लिक करें। –

+0

काम नहीं किया, लेकिन इसने इसे थोड़ा –

39

टपल मूल्य निर्दिष्ट करने के लिए आप __new__ विधि ओवरराइड करने के लिए की जरूरत है:

class Foo(tuple): 

    def __new__ (cls, a, b): 
     return super(Foo, cls).__new__(cls, tuple(b)) 

तर्क टपल वर्ग के __init__ कार्यान्वयन द्वारा नजरअंदाज कर दिया हो रहे हैं, लेकिन आप कुछ init सामान क्या करने की जरूरत है, तो आप इसे निम्न प्रकार से कर सकते हैं:

class Foo(tuple): 

    def __new__ (cls, a, b): 
     return super(Foo, cls).__new__(cls, tuple(b)) 

    def __init__(self, a, b): 
     self.a=a 
     self.b=b 

if __name__ == '__main__': 
    foo = Foo(None, [3, 4]) 
    print foo 
    print foo.a 
    print foo.b 
संबंधित मुद्दे