Я нашел конструкцию 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
Конечно, если вы можете различить возможные исключения, которые могут быть сгенерированы, вам не нужно использовать это, но если код, реагирующий на успешный фрагмент кода, может выдать то же исключение, что и успешный фрагмент, и вы можете просто отпустите второе возможное исключение или немедленно верните его в случае успеха (что в моем случае может привести к потере потока), тогда это пригодится.