2012-06-02 7 views
5

मैं पिछले कुछ घंटों से इसे समझने की कोशिश कर रहा हूं, और मैं हार मानने वाला हूं।पायथन जांच __init__ पैरामीटर

आप कैसे सुनिश्चित करते हैं कि पायथन में केवल एक मिलान करने वाला विशिष्ट मानदंड वस्तु उत्पन्न करेगा?

उदाहरण के लिए, मान लीजिए कि मैं ऑब्जेक्ट हैंड बनाना चाहता हूं, और केवल एक हाथ शुरू करना जब मेरे पास प्रारंभिक में पर्याप्त फिंगर्स हों? (सिर्फ एक सादृश्य के रूप में इस ले कृपया)

कहो,

class Hand: 
    def __init__(self, fingers): 
    # make sure len(fingers)==5, and 
    #only thumb, index, middle, ring, pinky are allowed in fingers 
    pass 

धन्यवाद।

ये मेरे सबसे नज़दीकी प्रश्न हैं, लेकिन एक सी ++ में है, दूसरा मेरे प्रश्न का उत्तर नहीं देता है।

checking of constructor parameter

How to overload __init__ method based on argument type?

+1

यदि ऐसा नहीं है तो आप क्या करना चाहते हैं? क्या आप इसे किसी प्रकार का अपवाद उठाना चाहते हैं? – BrenBarn

+0

मुझे लगता है कि यह एक अच्छा तरीका होगा। बस यह सुनिश्चित करने के लिए कि मैं गलत वस्तु नहीं बना रहा हूं। – chemelnucfin

उत्तर

5

आप उस के लिए __new__ परिभाषित करने के लिए है:

class Foo(object): 
    def __new__(cls, arg): 
     if arg > 10: #error! 
      return None 
     return super(Foo, cls).__new__(cls) 

print Foo(1) # <__main__.Foo object at 0x10c903410> 
print Foo(100) # None 

जिसके अनुसार, __init__ का उपयोग करने और Inva पर एक अपवाद को ऊपर उठाने ढक्कन तर्क आमतौर पर बेहतर होता है:

class Foo(object): 
    def __init__(self, arg): 
     if arg > 10: #error! 
      raise ValueError("invalid argument!") 
     # do stuff 
+5

'__new__' को परिभाषित करने की शायद ही कभी आवश्यकता है, और इससे' कोई नहीं 'वापस लौटना भयानक है। एक अतुलनीय त्रुटि के साथ दुर्घटनाग्रस्त होने से पहले बस कुछ पंक्तियों (या एक दर्जन फ़ंक्शन कॉल, यदि आपको बुरी किस्मत मिली है) के लिए जाने के बजाय अपवाद फेंक दें। – delnan

+0

@ डेलनान - तकनीकी रूप से, यदि ओपी गंभीर है, तो "केवल एक मिलान करने वाला विशिष्ट मानदंड वस्तु उत्पन्न करेगा," __new__' को परिभाषित करने की आवश्यकता होगी, क्योंकि '__init__' को एक ऑब्जेक्ट कहा जाता है जिसे पहले से ही बनाया गया है (अभी भी, आप सही हैं कि '__new__' में अपवाद उठाना कोई भी वापस करने से बेहतर होगा)। लेकिन मैं अनुमान लगा रहा हूं कि ओपी का वास्तव में मतलब यह नहीं है कि, इस मामले में '__init__' संस्करण निश्चित रूप से बेहतर है। – weronika

+0

@weronika जब तक गहरे जादू और भयानक हैकरी शामिल नहीं है, '__init__' में अपवाद उठाने से सभी को वास्तव में निर्मित वस्तु का संदर्भ प्राप्त करने से रोकता है। तो एक पर्यवेक्षक के पीओवी से एक भयानक एपीआई होने के अलावा कोई अंतर नहीं है। – delnan

0

जोर देते हुए प्रयास करें:

class Hand(object): 
    def __init__(self,fingers): 
     assert len(fingers) == 5 
     for fing in ("thumb","index","middle","ring","pinky"): 
      assert fingers.has_key(fing) 
+4

नहीं, 'assert' * आंतरिक * इनविरिएंट सत्यापित करने के लिए है: यह जांचना कि * आपका * कोड बहुत टूटा नहीं है। 'AssertionError' कॉलर को कोई उपयोगी जानकारी नहीं बताता है, और उसे लगता है कि आपका कोड टूटा हुआ है। इसके अलावा, दावों को 'ओओ' द्वारा छीन लिया जाता है। एक 'ValueError' या' RuntimeError' या जो भी विशिष्ट उपयोग केस के लिए उपयुक्त है फेंको। – delnan

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