अजगर: एक पंक्ति में कथन आज़माएँ


97

क्या एक कोशिश में / एक ही लाइन को छोड़कर, अजगर में एक तरीका है?

कुछ इस तरह...

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

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

जवाबों:


63

पायथन में एक लाइन पर 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:।)


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

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

यह एक तानाशाही के भीतर टुपल्स के एक बड़े सेट का हिस्सा है ... मैं बस चीजों को छोटा करने की कोशिश कर रहा था
Brant

2
getयदि आप अपवाद नहीं चाहते हैं तो उपयोग न करें । filterइसके बजाय उपयोग करें ।
18

@ मायकेग्राम अच्छा जवाब - एक संकेत (लिंक?) शॉर्ट-सर्किटिंग क्यों है त्रुटि प्रवण अच्छा होगा।
क्रतेंको

85

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

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

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

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


26
अरे, यह सवाल का जवाब देता है! :)
स्टीव बेनेट

4
इस जवाब को प्यार करो, सुपर गन्दा, लेकिन एक पंक्ति, जिस तरह से मुझे यह पसंद है।
पैट्रिक कुक 3

ये है जवाब !! वह problem[0]क्या लौटाएगा जो फ़ंक्शन देता है?
SIslam

5
Exec एक कोड गंध है और इससे बचा जाना चाहिए जब तक कि कुछ और काम न करे। यदि एक पंक्ति कोड इतना महत्वपूर्ण है तो यह काम करेगा, लेकिन आपको स्वयं से यह पूछने की आवश्यकता है कि एक पंक्ति इतनी महत्वपूर्ण क्यों है।
ग्यूथेन

4
स्पष्ट रूप से उत्पादन के उपयोग के लिए नहीं, लेकिन एक अजीब डिबगिंग सत्र के लिए वास्तव में क्या आवश्यक है।
थोरसुमोनर


13

एक अन्य तरीका एक संदर्भ प्रबंधक को परिभाषित करना है:

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

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

>>> 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

रनटाइम त्रुटि के मामले में कोई अपवाद नहीं उठाया जाएगा। यह try:बिना के जैसा है except:


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

10

सीमित अपेक्षित अपवादों के साथ poke53280 उत्तर का संस्करण।

def try_or(func, default=None, expected_exc=(Exception,)):
    try:
        return func()
    except expected_exc:
        return default

और इसे इस्तेमाल किया जा सकता है

In [2]: try_or(lambda: 1/2, default=float('nan'))
Out[2]: 0.5

In [3]: try_or(lambda: 1/0, default=float('nan'), expected_exc=(ArithmeticError,))
Out[3]: nan

In [4]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError,))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
[your traceback here]
TypeError: unsupported operand type(s) for /: 'str' and 'int'

In [5]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError, TypeError))
Out[5]: nan

के लिए "अपेक्षित_सेक्स = (अपवाद,)" में अल्पविराम क्या है? क्या आप समझा सकते हैं, कृपया
.बिल

1
एक करने के लिए अभिव्यक्ति @ibilgen अल्पविराम धर्मान्तरित टपल । लेखन (Exception)कोष्ठकों को छोड़ने के बराबर है। (Exception, )दुभाषिया को बताता है कि यह एक प्रविष्टि के साथ एक ट्यूपल (सूची की तरह कुछ) है। इस उदाहरण में इसका उपयोग किया जाता है इसलिए expected_excएक से अधिक अपवाद हो सकते हैं।
मीलिले


5

समस्या यह है कि इसका वास्तव में एक 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आदि


5

कैसे दो लाइनों का उपयोग करने के बारे में। ठीक है न ?

>>> try: a = 3; b= 0; c = a / b
... except : print('not possible'); print('zero division error')
...
not possible
zero division error

4

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

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

3
यह बिल्कुल वैसा ही काम नहीं करता है, जैसे कि एक चर निर्धारित किया गया है (हालांकि यह तब होता है जब आप किसी विशेष दायरे में रुचि रखते हैं।) इसके अलावा, ewwwwwwww .....
माइक ग्राहम

2

आपने उल्लेख किया कि आप django का उपयोग कर रहे हैं। यदि यह समझ में आता है कि आप क्या कर रहे हैं तो आप इसका उपयोग करना चाहते हैं:

my_instance, created = MyModel.objects.get_or_create()

createdसही या गलत होगा। शायद इससे आपको मदद मिलेगी।


2

पाइथन 3 पर काम करता है, जो वाल्टर मुंड से प्रेरित है

exec("try:some_problematic_thing()\nexcept:pass")

एक पंक्ति में mulitiples लाइनों के लिए

exec("try:\n\tprint('FirstLineOk')\n\tsome_problematic_thing()\n\tprint('ThirdLineNotTriggerd')\nexcept:pass")

Ps: आपके डेटा पर नियंत्रण नहीं करने के लिए Exec असुरक्षित है।


1

अगर आपको वास्तव में अपवादों को प्रबंधित करने की आवश्यकता है:
(poke53280 के उत्तर से संशोधित)

>>> def try_or(fn, exceptions: dict = {}):
    try:
        return fn()
    except Exception as ei:
        for e in ei.__class__.__mro__[:-1]:
            if e in exceptions: return exceptions[e]()
        else:
            raise


>>> def context():
    return 1 + None

>>> try_or( context, {TypeError: lambda: print('TypeError exception')} )
TypeError exception
>>> 

ध्यान दें कि यदि अपवाद समर्थित नहीं है, तो यह अपेक्षित रूप से बढ़ेगा:

>>> try_or( context, {ValueError: lambda: print('ValueError exception')} )
Traceback (most recent call last):
  File "<pyshell#57>", line 1, in <module>
    try_or( context, {ValueError: lambda: print('ValueError exception')} )
  File "<pyshell#38>", line 3, in try_or
    return fn()
  File "<pyshell#56>", line 2, in context
    return 1 + None
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
>>> 

अगर Exceptionदिया जाता है, तो यह नीचे कुछ भी मेल खाएगा।
( BaseExceptionयह अधिक है, इसलिए यह मेल नहीं खाएगा)

>>> try_or( context, {Exception: lambda: print('exception')} )
exception

0

यहां @surendra_ben द्वारा प्रदान किए गए उत्तर का एक सरल संस्करण है

a = "apple"try: a.something_that_definitely_doesnt_exist
except: print("nope")

...

nope

0

withएक पंक्ति में वाक्यविन्यास का उपयोग करें :

class OK(): __init__ = lambda self, *isok: setattr(self, 'isok', isok); __enter__ = lambda self: None; __exit__ = lambda self, exc_type, exc_value, traceback: (True if not self.isok or issubclass(exc_type, self.isok) else None) if exc_type else None

किसी भी त्रुटि को अनदेखा करें:

with OK(): 1/0

निर्दिष्ट त्रुटियों को अनदेखा करें:

with OK(ZeroDivisionError, NameError): 1/0
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.