2010-08-10 23 views
11

निम्नलिखित मान लीजिए:फ़ंक्शन एक टुपल या कोई नहीं लौटा रहा है: उस फ़ंक्शन को अच्छी तरह से कैसे कॉल करें?

def MyFunc(a): 
    if a < 0: 
    return None 
    return (a+1, a+2, a+3) 

v1, v2, v3 = MyFunc() 
# Bad ofcourse, if the result was None 

क्या एक समारोह है कि एक टपल देता है और अभी तक अच्छी तरह से कहा जा सकता है परिभाषित करने के लिए सबसे अच्छा तरीका है। वर्तमान में, मैं यह कर सकता है:


r = MyFunc() 
if r: 
    v1, v2, v3 = r 
else: 
    # bad!! 
    pass 

क्या मैं इस बारे में पसंद नहीं है मैं एक एकल चर का उपयोग करने के लिए और फिर इसे खोल होता है।

एक अन्य समाधान मैं समारोह एक टपल Nones की ताकि फोन करने वाले अच्छी तरह से खोल सकते हैं पूर्ण वापसी हो सकता है ....

किसी को भी एक बेहतर डिजाइन का सुझाव कर सकते हैं?

उत्तर

13

ArgumentError कैसे उठाएं? फिर आप try इसे कॉल कर सकते हैं, और तर्क गलत होने पर अपवाद से निपट सकते हैं।

तो, कुछ की तरह:

try: 
    v1, v2, v3 = MyFunc() 
except ArgumentError: 
    #deal with it 

इसके अलावा, ArgumentError का एक उपवर्ग प्रयोग करने के लिए katrielalex's answer देखते हैं।

+0

+1 मुझे पंच पर मारो! – katrielalex

+1

यह अच्छा है, लेकिन मैं हमेशा –

8

यह अच्छी तरह से काम करना चाहिए:

v1, v2, v3 = MyFunc() or (None, None, None) 

MyFunc() एक टपल देता है, यह अनपैक किया जाएगा, अन्यथा यह None की एक 3-टपल के लिए प्रतिस्थापित किया जाएगा।

+0

मुझे नहीं पता कि यह 'कोई नहीं' के टुपल को वापस करने से बेहतर कैसे है। – Skilldrick

+2

@ स्किलड्रिक: यह सुंदर है! – katrielalex

+0

यदि यह बेहतर है, तो शायद यह इसलिए है क्योंकि इसे फ़ंक्शन की सामग्री को बदलने की आवश्यकता नहीं है। – recursive

8

recursive वास्तव में सुरुचिपूर्ण और पायथनिक समाधान है। लेकिन: आप None क्यों वापस करना चाहते हैं? अजगर त्रुटियों से निपटने का एक तरीका है, और वह एक अपवाद को ऊपर उठाने के द्वारा होता है: इंगित करता है कि एक मूल्य के लौटने कि आप प्रोसेसिंग पूरी और हैं

class AIsTooSmallError(ArgumentError): pass 

और फिर

raise AIsTooSmallError("a must be positive.") 

कारण यह बेहतर है अपना जवाब वापस गुजर रहा है। यह ठीक है अगर आपने कुछ प्रसंस्करण किया है, लेकिन अगर आप तुरंत None लौट रहे हैं तो यह मूर्खतापूर्ण है।

+0

अपवादों को बढ़ाने और संभालने के ऊपरी हिस्से के बारे में चिंतित हूं :) लेकिन महान दिमाग ... – Skilldrick

+0

+1: त्रुटि को इंगित करने के लिए कोई भी वापस न करें। – nosklo

+0

हे। तो तुम हो। लेकिन मैंने 'ArgumentError' subclassed! – katrielalex

3

एक अन्य समाधान मैं समारोह एक टपल Nones की ताकि फोन करने वाले अच्छी तरह से खोल सकते हैं पूर्ण वापसी हो सकता है ....

क्या उस के साथ गलत क्या है? संगति एक अच्छी बात है।

+0

मैं सहमत हूं। असल में इस तरह से यह कार्य के वापसी हस्ताक्षर को बनाए रखता है। +1 – simplyharsh

+2

रिटर्न हस्ताक्षर बनाए रखना बहुत स्थिर है;) – Skilldrick

+0

@ स्किलड्रिक: मेरे अनुभव में, एक सतत वापसी हस्ताक्षर एक मूर्खतापूर्ण विवरण और अपवादों से अनजान रहने की इजाजत देकर गतिशीलता को बढ़ावा देता है। लेकिन मैं सिर्फ आलसी हूँ। –

1

यदि आप v1, v2, v3 ऑब्जेक्ट्स मौजूद हैं और किसी त्रुटि के मामले में डिफ़ॉल्ट मान पर सेट होना चाहते हैं, तो डिफ़ॉल्ट मान स्वयं को वापस कर दें।दूसरी ओर

def MyFunc(a): 
    if a < 0: 
     # can't use a negative value; just return some defaults 
     return (None, None, None) 
    return (a+1, a+2, a+3) 

, यदि डिफ़ॉल्ट वापसी उचित नहीं है और एक नकारात्मक तर्क एक गंभीर त्रुटि माना जाता है, एक अपवाद बढ़ा: यह फोन करने वाले पर निर्भर नहीं द्वारा बुला कोड सरल कर देगा उन्हें मैन्युअल रूप से स्थापित करने के लिए :

def MyFunc(a): 
    if a < 0: 
     # sorry, negative values are unacceptable 
     raise ValueError('cannot accept a negative value') 
    return (a+1, a+2, a+3) 

तीसरे कठिन पर, लौटने None बेहतर कभी कभी जब एक वस्तु लौटने re मॉड्यूल के search() और match() कार्यों के साथ मामला है हो सकता है। यह किसी भी तरह पहले दो मामलों के बीच खड़ा है, क्योंकि मिलान विफलता एक अपेक्षित परिणाम है, जबकि एक डिफ़ॉल्ट वापसी वस्तु वैसे भी बहुत उपयोगी नहीं होगी।

1

यह पिछले उत्तर के समान है। आप या तो ऑब्जेक्ट इंस्टेंस या कोई भी

def MyFunc(a): 
    class MyFuncClass(object): 
     def __init__(self, **kwargs): 
      self.__dict__.update(kwargs) 
    if a < 0: 
     return None 
    return MyFuncClass(one=a+1, two=a+2, three=a+3) 

o = MyFunc(1) 
if o is not None: 
    print o.one, o.two, o.three 
संबंधित मुद्दे