कथन के वैकल्पिक else
खंड का उपयोग क्या है try
?
कथन के वैकल्पिक else
खंड का उपयोग क्या है try
?
जवाबों:
यदि कोई अपवाद नहीं था, तो else
ब्लॉक में बयान निष्पादित किए जाते हैं - यदि निष्पादन नीचे से नीचे गिरता try
है। ईमानदारी से, मुझे कभी कोई आवश्यकता नहीं मिली।
हालाँकि, अपवाद नोटों को संभालना :
अन्य क्लॉज़ का उपयोग अतिरिक्त कोड को कोशिश क्लॉज़ में जोड़ने से बेहतर है क्योंकि यह गलती से एक अपवाद को पकड़ने से बचता है जो कि कोड द्वारा संरक्षित नहीं किया जा रहा था ... बयान को छोड़कर।
इसलिए, यदि आपके पास एक ऐसी विधि है जो उदाहरण के लिए, ए को फेंक सकती है IOError
, और आप अपवादों को पकड़ना चाहते हैं, लेकिन यह कुछ और है जो आप करना चाहते हैं यदि पहला ऑपरेशन सफल होता है, और आप एक IOError को नहीं पकड़ना चाहते हैं वह ऑपरेशन, आप कुछ इस तरह से लिख सकते हैं:
try:
operation_that_can_throw_ioerror()
except IOError:
handle_the_exception_somehow()
else:
# we don't want to catch the IOError if it's raised
another_operation_that_can_throw_ioerror()
finally:
something_we_always_need_to_do()
यदि आप another_operation_that_can_throw_ioerror()
बाद में डालते हैं operation_that_can_throw_ioerror
, except
तो दूसरी कॉल की त्रुटियों को पकड़ लेगा। और अगर आप इसे पूरे try
ब्लॉक के बाद लगाते हैं, तो यह हमेशा चलता रहेगा, और इसके बाद तक नहीं finally
। else
आप यह सुनिश्चित कर लें की सुविधा देता है
finally
ब्लॉक से पहले चलाया जाता है, औरIOError
उठाता है यहाँ पकड़ा नहीं हैreturn
, continue
या के कारण भी होता है break
।
उपयोग करने का एक बड़ा कारण है else
- शैली और पठनीयता। यह आमतौर पर कोड रखने का एक अच्छा विचार है जो उस कोड के पास अपवाद का कारण बन सकता है जो उनके साथ व्यवहार करता है। उदाहरण के लिए, इनकी तुलना करें:
try:
from EasyDialogs import AskPassword
# 20 other lines
getpass = AskPassword
except ImportError:
getpass = default_getpass
तथा
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
else:
# 20 other lines
getpass = AskPassword
दूसरा अच्छा है जब except
जल्दी वापस नहीं आ सकता है, या अपवाद को फिर से फेंक सकता है। यदि संभव हो तो, मैंने लिखा होता:
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
return False # or throw Exception('something more descriptive')
# 20 other lines
getpass = AskPassword
नोट: उत्तर हाल ही में पोस्ट किए गए डुप्लिकेट से कॉपी किया गया है , इसलिए यह सब "AskPassword" सामान है।
एक उपयोग: कुछ कोड का परीक्षण करें जो एक अपवाद को बढ़ाएं।
try:
this_should_raise_TypeError()
except TypeError:
pass
except:
assert False, "Raised the wrong exception type"
else:
assert False, "Didn't raise any exception"
(यह कोड व्यवहार में अधिक सामान्य परीक्षण में सार होना चाहिए।)
अजगर कोशिश-और
else
कोशिश बयान के वैकल्पिक खंड का उपयोग क्या है ?
यदि कोई अपवाद नहीं था, तो इसे चलाने के लिए अधिक उपयोग के लिए एक संदर्भ का उपयोग करने का इरादा था, जहां इसे संभाला जाने की उम्मीद थी।
यह संदर्भ गलती से निपटने की त्रुटियों से बचता है जिसकी आपको उम्मीद नहीं थी।
लेकिन उन सटीक स्थितियों को समझना महत्वपूर्ण है जो दूसरे खंड को चलाने का कारण बनते हैं, क्योंकि return
, continue
, और break
करने के लिए नियंत्रण प्रवाह बाधित कर सकते हैं else
।
else
बयान चलता है, तो देखते हैं कोई अपवाद और एक से बाधित नहीं करता है, तो return
, continue
या break
बयान।
else
यदि और जब नियंत्रण समाप्त होता है तो वैकल्पिक क्लॉज निष्पादित किया जाता हैtry
खंड से ।
(बोलिंग जोड़ी गई।) और पाद लेख पढ़ता है:
* वर्तमान में, नियंत्रण एक अपवाद के मामले या एक के निष्पादन को छोड़कर "अंत बंद बहती है"
return
,continue
याbreak
बयान।
यह खंड ( व्याकरण देखें ) को छोड़कर कम से कम एक पूर्ववर्ती की आवश्यकता है । तो यह वास्तव में "try-else," नहीं है, यह "try-छोड़कर-और (-finally)" के साथ हैelse
(और finally
) वैकल्पिक होने के साथ।
अजगर ट्यूटोरियल इरादा उपयोग पर बताते हैं:
कोशिश ... बयान को छोड़कर वैकल्पिक वैकल्पिक खंड है, जो वर्तमान में, खंड को छोड़कर सभी का पालन करना चाहिए। यह कोड के लिए उपयोगी है जिसे निष्पादित किया जाना चाहिए यदि प्रयास खंड अपवाद नहीं उठाता है। उदाहरण के लिए:
for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print 'cannot open', arg else: print arg, 'has', len(f.readlines()), 'lines' f.close()
अन्य क्लॉज़ का उपयोग अतिरिक्त कोड को कोशिश क्लॉज़ में जोड़ने से बेहतर है क्योंकि यह गलती से एक अपवाद को पकड़ने से बचता है जो कि कोड द्वारा संरक्षित नहीं किया जा रहा था ... बयान को छोड़कर।
else
try
ब्लॉक के बाद कोड बनामयदि आप एक त्रुटि संभालते हैं, तो else
ब्लॉक नहीं चलेगा। उदाहरण के लिए:
def handle_error():
try:
raise RuntimeError('oops!')
except RuntimeError as error:
print('handled a RuntimeError, no big deal.')
else:
print('if this prints, we had no error!') # won't print!
print('And now we have left the try block!') # will print!
और अब,
>>> handle_error()
handled a RuntimeError, no big deal.
And now we have left the try block!
ईआरएफपी पैटर्न को डक-टाइपिंग के साथ जोड़ने के लिए ट्राइ - एक्सटर -और महान है :
try:
cs = x.cleanupSet
except AttributeError:
pass
else:
for v in cs:
v.cleanup()
आप इस भोले कोड ठीक है बात कर सकते हैं:
try:
for v in x.cleanupSet:
v.clenaup()
except AttributeError:
pass
यह गलती से अपने कोड में गंभीर कीड़े को छिपाने का एक शानदार तरीका है। मैं वहां टाइप-एड क्लीनअप करता हूं, लेकिन एट्रीब्यूटर मुझे बताएंगे कि निगल लिया जा रहा है। इससे भी बदतर, क्या होगा अगर मैं इसे सही तरीके से लिखूं, लेकिन सफाई विधि कभी-कभी एक उपयोगकर्ता प्रकार पारित किया जा रहा था जिसमें एक गलत विशेषता थी, जिससे यह चुपचाप आधे रास्ते में विफल हो जाए और एक फाइल को छोड़ दिया जाए? सौभाग्य है कि एक डिबगिंग।
मुझे यह वास्तव में उपयोगी लगता है जब आप सफाई कर चुके होते हैं जो कि अपवाद होने पर भी करना पड़ता है:
try:
data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
handle_exception(e)
else:
do_stuff(data)
finally:
clean_up()
भले ही आप अभी इसके उपयोग के बारे में नहीं सोच सकते, लेकिन आप शर्त लगा सकते हैं कि इसके लिए एक उपयोग होना चाहिए। यहाँ एक अकल्पनीय नमूना है:
के साथ else
:
a = [1,2,3]
try:
something = a[2]
except:
print "out of bounds"
else:
print something
इसके बिना else
:
try:
something = a[2]
except:
print "out of bounds"
if "something" in locals():
print something
something
यदि आपके पास कोई त्रुटि नहीं है, तो यहां आपको वैरिएबल परिभाषित किया गया है। आप इसे try
ब्लॉक से बाहर निकाल सकते हैं , लेकिन इसके बाद कुछ गड़बड़ का पता लगाने की आवश्यकता होती है यदि एक चर परिभाषित किया गया है।
something = a[2]; print something
प्रयास के अंदर क्या गलत है : ब्लॉक?
PEP 380try-else
में एक अच्छा उदाहरण है । मूल रूप से, यह एल्गोरिथ्म के विभिन्न भागों में अलग-अलग अपवाद हैंडलिंग करने के लिए नीचे आता है।
यह कुछ इस तरह है:
try:
do_init_stuff()
except:
handle_init_suff_execption()
else:
try:
do_middle_stuff()
except:
handle_middle_stuff_exception()
यह आपको अपवाद हैंडलिंग कोड को लिखने की अनुमति देता है जहां अपवाद होता है।
से त्रुटियों और अपवाद # अपवाद हैंडलिंग - docs.python.org
try ... except
बयान एक वैकल्पिक हैelse
खंड है, जो है, जब वर्तमान, खंड को छोड़कर सभी का पालन करना होगा। यह कोड के लिए उपयोगी है जिसे निष्पादित किया जाना चाहिए यदि प्रयास खंड अपवाद नहीं उठाता है। उदाहरण के लिए:for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print 'cannot open', arg else: print arg, 'has', len(f.readlines()), 'lines' f.close()
अन्य क्लॉज़ का उपयोग अतिरिक्त कोड को कोशिश क्लॉज़ में जोड़ने से बेहतर है क्योंकि यह गलती से एक अपवाद को पकड़ने से बचता है जो कि कोड द्वारा संरक्षित नहीं किया जा रहा था ... बयान को छोड़कर।
पायथन संदर्भ को देखते हुए ऐसा लगता है कि जब कोई अपवाद नहीं है, तब else
इसे निष्पादित किया जाता try
है। वैकल्पिक क्लॉज को तब निष्पादित किया जाता है, जब और जब नियंत्रण क्लॉज के अंत में बहता है। 2 अन्य खंडों में अपवाद पूर्ववर्ती खंडों को छोड़कर नहीं संभाले जाते हैं।
अजगर में गोता लगाने का एक उदाहरण है, जहां अगर मैं सही तरीके से समझूं, तो try
ब्लॉक में वे एक मॉड्यूल को आयात करने की कोशिश करते हैं, जब वह विफल हो जाता है तो आप अपवाद प्राप्त करते हैं और डिफ़ॉल्ट रूप से बांधते हैं लेकिन जब यह काम करता है तो आपके पास जाने का एक विकल्प होता हैelse
ब्लॉक और जो आवश्यक है उसे बांधने का है (देखें उदाहरण और स्पष्टीकरण के लिए लिंक)।
यदि आप catch
ब्लॉक में काम करने की कोशिश करते हैं तो यह एक और अपवाद फेंक सकता है - मुझे लगता है कि जहां else
ब्लॉक काम आता है।
try
ब्लॉक से बाहर लौट सकते हैं ।
बस। एक प्रयास को छोड़कर खंड का The और ’खंड कोड के लिए मौजूद है जो कि (और केवल तब) चलता है जब कोशिश की गई कार्रवाई सफल होती है। इसका उपयोग किया जा सकता है, और इसका दुरुपयोग किया जा सकता है।
try:
fp= open("configuration_file", "rb")
except EnvironmentError:
confdata= '' # it's ok if the file can't be opened
else:
confdata= fp.read()
fp.close()
# your code continues here
# working with (possibly empty) confdata
व्यक्तिगत रूप से, मैं इसे पसंद करता हूं और उचित होने पर इसका उपयोग करता हूं। यह शब्दार्थ समूहों का कथन है।
शायद एक उपयोग हो सकता है:
#debug = []
def debuglog(text, obj=None):
" Simple little logger. "
try:
debug # does global exist?
except NameError:
pass # if not, don't even bother displaying
except:
print('Unknown cause. Debug debuglog().')
else:
# debug does exist.
# Now test if you want to log this debug message
# from caller "obj"
try:
if obj in debug:
print(text) # stdout
except TypeError:
print('The global "debug" flag should be an iterable.')
except:
print('Unknown cause. Debug debuglog().')
def myfunc():
debuglog('Made it to myfunc()', myfunc)
debug = [myfunc,]
myfunc()
शायद इससे आपको बहुत फायदा होगा।
मैंने try: ... else:
निर्माण को उस स्थिति में उपयोगी पाया है जहां आप डेटाबेस क्वेरी चला रहे हैं और उन प्रश्नों के परिणामों को उसी स्वाद या प्रकार के एक अलग डेटाबेस में लॉग कर रहे हैं। मान लें कि मेरे पास बहुत सारे वर्कर थ्रेड हैं, जो एक कतार में सबमिट किए गए डेटाबेस क्वेरीज़ को हैंडल करते हैं
#in a long running loop
try:
query = queue.get()
conn = connect_to_db(<main db>)
curs = conn.cursor()
try:
curs.execute("<some query on user input that may fail even if sanitized">)
except DBError:
logconn = connect_to_db(<logging db>)
logcurs = logconn.cursor()
logcurs.execute("<update in DB log with record of failed query")
logcurs.close()
logconn.close()
else:
#we can't put this in main try block because an error connecting
#to the logging DB would be indistinguishable from an error in
#the mainquery
#We can't put this after the whole try: except: finally: block
#because then we don't know if the query was successful or not
logconn = connect_to_db(<logging db>)
logcurs = logconn.cursor()
logcurs.execute("<update in DB log with record of successful query")
logcurs.close()
logconn.close()
#do something in response to successful query
except DBError:
#This DBError is because of a problem with the logging database, but
#we can't let that crash the whole thread over what might be a
#temporary network glitch
finally:
curs.close()
conn.close()
#other cleanup if necessary like telling the queue the task is finished
बेशक, यदि आप संभावित अपवादों के बीच अंतर कर सकते हैं जो फेंक दिया जा सकता है, तो आपको इसका उपयोग करने की आवश्यकता नहीं है, लेकिन यदि कोड सफल कोड पर प्रतिक्रिया कर रहा है तो वही अपवाद फेंक सकता है जो सफल टुकड़ा है, और आप बस नहीं कर सकते दूसरे संभावित अपवाद को जाने दें, या सफलता पर तुरंत लौटें (जो मेरे मामले में धागे को मार देगा), तो यह काम में आता है।
एक else
ब्लॉक अक्सर कार्यक्षमता को पूरक करने के लिए मौजूद हो सकता है जो हर except
ब्लॉक में होता है ।
try:
test_consistency(valuable_data)
except Except1:
inconsistency_type = 1
except Except2:
inconsistency_type = 2
except:
# Something else is wrong
raise
else:
inconsistency_type = 0
"""
Process each individual inconsistency down here instead of
inside the except blocks. Use 0 to mean no inconsistency.
"""
इस मामले में, inconsistency_type
ब्लॉक को छोड़कर प्रत्येक में सेट किया गया है, ताकि व्यवहार में कोई त्रुटि मामले में पूरक हो else
।
बेशक, मैं इसे एक पैटर्न के रूप में वर्णित कर रहा हूं जो किसी दिन आपके अपने कोड में बदल सकता है। इस विशिष्ट मामले में, आप वैसे भी ब्लॉक inconsistency_type
से पहले 0 पर सेट होते हैं try
।
यहाँ एक और जगह है जहाँ मुझे इस पैटर्न का उपयोग करना पसंद है:
while data in items:
try
data = json.loads(data)
except ValueError as e:
log error
else:
# work on the `data`
continue
इसके बजाय सिर्फ उपयोग कर सकते हैं - "ब्रेक आउट अर्ली" पैटर्न। यह आपको "और" खंड और इसके इंडेंटेशन को छोड़ने की अनुमति देता है, जिससे कोड को पढ़ना आसान हो जाता है।
मेरे द्वारा उपयोग किए जा सकने वाले उपयोग परिदृश्यों में से एक अप्रत्याशित अपवाद है, जिसे यदि आप फिर से प्रयास करते हैं, तो इसे दरकिनार किया जा सकता है। उदाहरण के लिए, जब ट्राई ब्लॉक में परिचालनों में यादृच्छिक संख्याएँ शामिल होती हैं:
while True:
try:
r = random.random()
some_operation_that_fails_for_specific_r(r)
except Exception:
continue
else:
break
लेकिन अगर अपवाद की भविष्यवाणी की जा सकती है, तो आपको हमेशा अपवाद से पहले सत्यापन को चुनना चाहिए। हालांकि, हर चीज की भविष्यवाणी नहीं की जा सकती है, इसलिए इस कोड पैटर्न का अपना स्थान है।
break
अंदर डालकर कर सकते हैं try
, जो क्लीनर IMO है, और आपको इसकी आवश्यकता नहीं है else
। इसके अलावा continue
वास्तव में जरूरत नहीं है, आप बस कर सकते हैं pass
।
मैंने else
संभवतः एक गलत कॉन्फ़िगरेशन फ़ाइल से निपटने के लिए उपयोगी पाया है:
try:
value, unit = cfg['lock'].split()
except ValueError:
msg = 'lock monitoring config must consist of two words separated by white space'
self.log('warn', msg)
else:
# get on with lock monitoring if config is ok
lock
कॉन्फ़िगरेशन पढ़ने वाला एक अपवाद लॉक मॉनिटरिंग को अक्षम करता है और ValueErors एक उपयोगी चेतावनी संदेश लॉग करते हैं।
मान लीजिए कि आपका प्रोग्रामिंग तर्क इस बात पर निर्भर करता है कि किसी शब्दकोश में किसी दिए गए कुंजी के साथ प्रविष्टि है या नहीं। आप निर्माण का dict.get(key)
उपयोग करने के परिणाम का परीक्षण if... else...
कर सकते हैं, या आप कर सकते हैं:
try:
val = dic[key]
except KeyError:
do_some_stuff()
else:
do_some_stuff_with_val(val)
मैं एक और उपयोग के मामले को जोड़ूंगा जो DB सत्रों को संभालने पर सीधे आगे लगता है:
# getting a DB connection
conn = db.engine.connect()
# and binding to a DB session
session = db.get_session(bind=conn)
try:
# we build the query to DB
q = session.query(MyTable).filter(MyTable.col1 == 'query_val')
# i.e retrieve one row
data_set = q.one_or_none()
# return results
return [{'col1': data_set.col1, 'col2': data_set.col2, ...}]
except:
# here we make sure to rollback the transaction,
# handy when we update stuff into DB
session.rollback()
raise
else:
# when no errors then we can commit DB changes
session.commit()
finally:
# and finally we can close the session
session.close()
else:
ब्लॉक भ्रमित और (लगभग) बेकार है। यह for
और while
कथनों का भी हिस्सा है ।
वास्तव में, यहां तक कि if
-statement पर भी ,else:
वास्तव में भयानक तरीके से दुर्व्यवहार किया जा सकता है जो कीड़े पैदा कर रहे हैं जिन्हें ढूंढना बहुत कठिन है।
इस पर विचार करो।
if a < 10:
# condition stated explicitly
elif a > 10 and b < 10:
# condition confusing but at least explicit
else:
# Exactly what is true here?
# Can be hard to reason out what condition is true
दो बार के बारे में सोचो else:
। यह आमतौर पर एक समस्या है। इसके अलावा एक if
कमी से बचें और फिर भी else
इसे स्पष्ट करने के लिए दस्तावेज़ - स्थिति पर विचार करें ।
if x > 0: return "yes"
और if x <= 0: return "no"
। अब एक व्यक्ति आता है और कहने के लिए शर्तों में से x > 1
एक को बदल देता है लेकिन दूसरे को बदलने के लिए भूल जाता है। यह कैसे कम हो जाएगा कि कीड़े की संख्या कम हो जाएगा। if else
खंड कभी-कभी कई रेखाएँ अलग हो जाती हैं। DRY एक अच्छा अभ्यास है, वास्तव में बहुत अधिक बार नहीं। (दुबारा पोस्ट करने के लिए क्षमा करें)।