2010-03-26 9 views
41

क्या एक लाइन में कोशिश करने के अलावा पाइथन में कोई तरीका है?पायथन: एक पंक्ति में कथन का प्रयास करें

कुछ की तरह ...

b = 'some variable' 
a = c | b #try statement goes here 

कहाँ b एक घोषित चर रहा है और c नहीं है ... इसलिए c एक त्रुटि फेंक और ab बन जाएगा ...

उत्तर

34

कोई है पाइथन में एक ही पंक्ति पर try/except ब्लॉक को संपीड़ित करने का तरीका।

साथ ही, यह जानना एक बुरी बात है कि पाइथन में एक चर मौजूद है, जैसे कि आप कुछ अन्य गतिशील भाषाओं में होंगे। सुरक्षित तरीका (और प्रचलित शैली) सभी चर को किसी चीज़ पर सेट करना है। वे सेट नहीं हो सकता है, उन्हें None पहले करने के लिए सेट (या 0 या '' या कुछ और अगर यह लागू है।)


आप सभी के नाम आप पहली बार में रुचि रखते हैं, तो आप ऐसा आवंटित कर हैं विकल्प हैं

  • सबसे अच्छा विकल्प एक कथन है।

    c = None 
    b = [1, 2] 
    
    if c is None: 
        a = b 
    else: 
        a = c 
    
  • एक-लाइनर विकल्प एक सशर्त अभिव्यक्ति है।

    c = None 
    b = [1, 2] 
    a = c if c is not None else b 
    
  • कुछ लोगों or से कम-सर्किटिंग व्यवहार दुरुपयोग ऐसा करने के लिए। यह त्रुटि प्रवण है, इसलिए मैंने कभी इसका उपयोग नहीं किया।

    c = None 
    b = [1, 2] 
    a = c or b 
    

    निम्नलिखित मामले पर विचार करें:

    c = [] 
    b = [1, 2] 
    a = c or b 
    

    इस मामले में, a शायद होना चाहिए [], लेकिन यह [1, 2] है क्योंकि [] एक बूलियन संदर्भ में गलत है। क्योंकि बहुत सारे मूल्य हैं जो झूठे हो सकते हैं, मैं or चाल का उपयोग नहीं करता हूं। (यह एक ही समस्या है जब वे कहते हैं कि जब वे if foo:if foo is not None: मतलब में लोगों को चलाया जाता है।)

+0

धन्यवाद। समस्या यह है कि यह वास्तव में एक django model.objects.get क्वेरी मैं परीक्षण करने की कोशिश कर रहा हूँ। अगर कोई डेटा नहीं मिलता है तो .get एक त्रुटि देता है ... यह वापस नहीं लौटाता है (जो मुझे परेशान करता है) – Brant

+2

@ ब्रेंट, तो आप त्रुटि क्यों नहीं पकड़ सकते? एक लाइन क्यों? –

+0

@ ब्रेंट, ठीक है, यह स्थिति जांचने से थोड़ा अलग है कि एक चर सेट है (पायथन में कोई चर घोषित नहीं किया गया है)। पाइथन में सामान्य शैली त्रुटियों को मानने के लिए अपवादों को बढ़ाने के लिए अपवादों को प्राथमिकता देना पसंद करती है, जिनमें से हम में से कई वास्तव में प्यार करते हैं। हर बार एक ऑपरेशन के रिटर्न कोड की जांच करने और त्रुटियों को ट्रैक करने में कठिन समय होने पर यदि मैं कुछ नहीं करता तो मुझे निश्चित रूप से पायथन लिखते समय सी के बारे में याद नहीं आती है। किसी भी घटना में, हालांकि इस पर चर्चा की गई है, 'ब्लॉक' को छोड़कर 'try' /' के लिए कोई भी लाइन सिंटैक्स नहीं है। सौभाग्य से लाइनें सस्ते हैं, इसलिए 4-लाइन समाधान आपके लिए काम करना चाहिए। ;-) –

2

आपने कहा है कि आप Django का उपयोग कर रहे हैं। यह आप कर रहे हैं क्या आप उपयोग करना चाहते हो सकता है के लिए समझ में आता है, तो:

my_instance, created = MyModel.objects.get_or_create() 

created सही है या गलत हो जाएगा। शायद यह आपकी मदद करेगा।

4

आप vars(), locals(), या globals() का उपयोग कर नेमस्पेस dict तक पहुंचकर ऐसा कर सकते हैं, जो भी आपकी स्थिति के लिए सबसे उपयुक्त है।

>>> b = 'some variable' 
>>> a = vars().get('c', b) 
+3

पोस्ट में मेरा उदाहरण देखें, यह एक वैरिएबल सेट है या नहीं, यह जांचने के समान ही काम नहीं करता है (हालांकि यदि आप किसी विशेष दायरे में रूचि रखते हैं तो यह भी करता है।) इसके अलावा, ewwwwwwww ..... –

53

यह बहुत hackish है, लेकिन मैं इसे का उपयोग किया है प्रॉम्प्ट पर जब मैं डिबगिंग के लिए गतिविधियों का क्रम ऊपर लिखना चाहते थे:

exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()" 
print "The problem is %s" % problem[1] 

अधिकांश भाग के लिए, मैं नहीं कर रहा हूँ बिना किसी एकल-लाइन-कोशिश-प्रतिबंधित प्रतिबंध को लेकर परेशान, लेकिन जब मैं बस प्रयोग कर रहा हूं और मैं इंटरैक्टिव दुभाषिया में एक बार कोड के पूरे हिस्से को याद करने के लिए रीडलाइन चाहता हूं ताकि मैं इसे किसी भी तरह समायोजित कर सकूं, यह छोटा चाल आसान काम में आता है।

वास्तविक उद्देश्य के लिए आप पूरा करने की कोशिश कर रहे हैं, तो आप locals().get('c', b) आज़मा सकते हैं; आदर्श रूप से स्थानीय संदर्भ के बजाय वास्तविक शब्दकोश का उपयोग करना बेहतर होगा, या जो कुछ भी हो सकता है या इसे सेट नहीं कर सकता है, उसे चलाने से पहले किसी को भी निर्दिष्ट नहीं करना चाहिए।

>>> with trial: a = 5  # will be executed normally 
>>> with trial: a = 1/0 # will be not executed and no exception is raised 
>>> print a 
5 

कोई अपवाद एक क्रम के मामले में बढ़ा दी जाएगी:

class trialContextManager: 
    def __enter__(self): pass 
    def __exit__(self, *args): return True 
trial = trialContextManager() 

फिर एक ही पंक्ति में त्रुटियों को अनदेखा करने के लिए with बयान का उपयोग करें:

+12

अरे, यह सवाल का जवाब है! :) –

+2

इस उत्तर को प्यार करें, सुपर गन्दा, लेकिन एक पंक्ति, जिस तरह से मुझे यह पसंद है। –

+0

यह जवाब है !! समस्या होगी [0] 'वह कार्य वापस लौटाएगा? – SIslam

3

एक और तरीका है एक संदर्भ प्रबंधक परिभाषित करने के लिए है त्रुटि। यह except: के बिना try: जैसा है।

+1

यह बहुत अच्छा है! चूंकि कोई स्पष्ट प्रयास नहीं है/सिवाय इसके कि, क्या आप संक्षेप में समझा सकते हैं कि संदर्भ प्रबंधक त्रुटियों से कैसे निपटता है? – Patrick

0

समस्या यह है कि यह वास्तव में एक django model.objects.get क्वेरी है जिसे मैं परीक्षण करने की कोशिश कर रहा हूं। .Get एक त्रुटि देता है यदि कोई डेटा नहीं मिला है ... यह वापस नहीं करता है कोई नहीं (जो मुझे गुस्सा दिलाती है)

कुछ इस तरह का प्रयोग करें:

print("result:", try_or(lambda: model.objects.get(), '<n/a>')) 

कहाँ try_or एक उपयोगिता समारोह में परिभाषित किया गया है आप द्वारा:

def try_or(fn, default): 
    try: 
     return fn() 
    except: 
     return default 

वैकल्पिक रूप से आप को स्वीकार कर लिया अपवाद टाइप NameError, AttributeError करने, आदि प्रतिबंधित कर सकते हैं

1
parse_float = lambda x, y=exec("def f(s):\n try:\n return float(s)\n except: return None"): f(x) 

हमेशा एक समाधान होता है।

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