2012-09-30 10 views
13

का उपयोग कर पाइथन ऑब्जेक्ट्स पाइथन के डेटा मॉडल के बारे में सीखने में, मैं __new__ विधि का उपयोग कर मौजूदा ऑब्जेक्ट्स से ऑब्जेक्ट्स बनाने के साथ खेल रहा हूं। यहाँ कुछ उदाहरण हैं जो विभिन्न प्रकार के नए वस्तुओं को बनाने हैं:पायथन ऑब्जेक्ट्स __new__

x = 2;  print type(x).__new__(x.__class__) 
x = {}; print type(x).__new__(x.__class__) 
x = [1,2]; print type(x).__new__(x.__class__) 
x = 2.34; print type(x).__new__(x.__class__) 
x = '13'; print type(x).__new__(x.__class__) 
x = 1.0j; print type(x).__new__(x.__class__) 
x = True; print type(x).__new__(x.__class__) 
x = (1,2); print type(x).__new__(x.__class__) 

हालांकि, निम्नलिखित तीन प्रयोगों मुझे त्रुटियों दे:

x = None;   print type(x).__new__(x.__class__) 
x = lambda z: z**2; print type(x).__new__(x.__class__) 
x = object;   print type(x).__new__(x.__class__) 

त्रुटियों (क्रमशः) कर रहे हैं:

TypeError: object.__new__(NoneType) is not safe, use NoneType.__new__() 
TypeError: Required argument 'code' (pos 1) not found 
TypeError: type() takes 1 or 3 arguments 

इन तीन उदाहरण क्यों काम नहीं करते? (नोट: lambda उदाहरण के लिए ऐसा लगता है कि जब मैं __new__ विधि का आह्वान करता हूं तो मुझे कोड खंड में पास करना होगा, लेकिन मुझे नहीं पता कि यह कैसे करना है।) मैं पायथन 2.6 का उपयोग कर रहा हूं।

कृपया ध्यान दें कि मुझे एहसास है कि यह आवश्यक नहीं है कि आप वास्तविक कोड में नई वस्तुएं बनाना चाहते हैं, लेकिन मेरा उद्देश्य व्यावहारिक नहीं है, बल्कि यह समझना है कि निम्न-स्तरीय ऑब्जेक्ट विधियां कैसे काम करती हैं।

+1

और वास्तव में क्या त्रुटि कहते हैं कि यह हमारे लिए benefitial हो जाएगा .. –

+0

जोड़ा संदेशों , रोहित। सलाह के लिये धन्यवाद। – rlandster

उत्तर

14

यह कुछ भी खास नहीं है, यह सिर्फ कुछ प्रकार के लिए उस प्रकार का एक डिफ़ॉल्ट "खाली" ऑब्जेक्ट है, जबकि अन्य लोगों के लिए नहीं है। आपके कामकाजी उदाहरण मूल रूप से बराबर हैं:

int() 
dict() 
list() 
float() 
str() 
complex() 
tuple() 

। । । जो सभी काम करते हैं। आपके पिछले तीन उदाहरण मूल रूप से किसी भी प्रकार के टाइप, function, और type के नए उदाहरण बनाने की कोशिश कर रहे हैं।

  1. कोई भी टाइप एक अद्वितीय कारण के लिए विफल रहता है, क्योंकि कोई भी सिंगलटन नहीं है --- कोई भी टाइप प्रकार केवल एक उदाहरण नहीं हो सकता है, अर्थात् कोई भी वस्तु नहीं। (आपको प्राप्त होने वाला विशिष्ट त्रुटि संदेश थोड़ा अजीब है, लेकिन यदि आप types.NoneType() करते हैं तो आपको "कोई भी उदाहरण उदाहरण नहीं बना सकता" कहने वाला एक और सीधा संदेश मिलेगा।)
  2. function विफल रहता है क्योंकि, जैसा कि आपने देखा, इसे एक की आवश्यकता है तर्क, और आप एक प्रदान नहीं करते हैं। आपको जो चाहिए वह कोड ऑब्जेक्ट है, जिसे आप किसी मौजूदा फ़ंक्शन से या compile फ़ंक्शन से प्राप्त कर सकते हैं। (इसे globals तर्क की भी आवश्यकता है, जो सिर्फ एक निर्देश हो सकता है।)
  3. type विफल रहता है क्योंकि आपने पर्याप्त तर्क नहीं दिए हैं। आप एक नया प्रकार (यानी, एक वर्ग) बनाने के लिए foo, या type(name, bases, dict) के प्रकार प्राप्त करने के लिए या तो type(foo) कर सकते हैं।

आकस्मिक रूप से नोटिस करें कि आपके अंतिम उदाहरण में आप object का प्रकार ले रहे हैं, जो स्वयं ही एक प्रकार है। यदि आप इसके बजाय x = object() करते हैं (एक्स को वस्तु प्रकार के बजाए एक व्यक्तिगत वस्तु बनाते हैं) तो यह काम करेगा और "रिक्त" ऑब्जेक्ट बनाएगा।

याद रखने की बात यह है कि __new__ पर कॉल करना वास्तव में जादुई नहीं है। यह तब होता है जब आप सीधे someType() कर प्रकार को तुरंत चालू करने का प्रयास करते हैं। यदि उस प्रकार के तर्कों की आवश्यकता है, तो __new__ पर कॉल करना असफल हो जाएगा, अगर आप इसे सही तर्क नहीं देते हैं तो किसी भी अन्य फ़ंक्शन कॉल की विफलता होगी, क्योंकि type(x).__new__ किसी अन्य फ़ंक्शन की तरह ही एक फ़ंक्शन है।आप इसे उपयोगकर्ता द्वारा परिभाषित कक्षा के साथ देख सकते हैं:

>>> class Foo(object): 
...  pass 
>>> x = Foo();   print type(x).__new__(x.__class__) 
<__main__.Foo object at 0x00EB0370> 
>>> class Foo(object): 
...  def __init__(self, someArg): 
...   pass 
>>> class Foo(object): 
...  def __new__(cls, someArg): 
...   return super(Foo, cls).__new__(cls) 
>>> x = Foo(2);   print type(x).__new__(x.__class__) 
Traceback (most recent call last): 
    File "<pyshell#32>", line 1, in <module> 
    x = Foo(2);   print type(x).__new__(x.__class__) 
TypeError: __new__() takes exactly 2 arguments (1 given) 

यह पहले मामले में सफल रहा, क्योंकि मेरी कक्षा को तर्क की आवश्यकता नहीं थी; यह दूसरी कक्षा में विफल रहा, क्योंकि दूसरी कक्षा में तर्क की आवश्यकता होती है।

__new__ किसी भी गुप्त कारण के लिए विफल नहीं है; यह बस विफल रहता है क्योंकि जिस प्रकार को आप तुरंत चालू करने का प्रयास कर रहे हैं उसे एक उदाहरण बनाने के लिए तर्क की आवश्यकता होती है। (None मामले में केवल एक ही है कि यहां अलग है है, कि एक, एक विशेष कारण के लिए असफल है क्योंकि None पायथन में एक विशेष वस्तु है।)

+0

बहुत स्पष्ट रूप से +1 समझाया – JamesSwift

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