What is the intended use of the optional else
clause of the try
statement?
-
4Most answers seem to concentrate on why we can't just put the material in the else clause in the try clause itself. The question https://stackoverflow.com/questions/3996329/ specifically asks why the else clause code cannot go *after* the try block itself, and that question is dupped to this one, but I do not see a clear reply to that question here. I feel https://stackoverflow.com/a/3996378/1503120 excellently answers that question. I have also tried to elucidate the various significance of the various clauses at https://stackoverflow.com/a/22579805/1503120. – jamadagni Mar 22 '14 at 16:39
-
2You want something to occur if the exception doesn't trigger, before the final cleanup, that isn't ever supposed to itself trigger the same exception handling. – benjimin Apr 17 '20 at 08:05
-
5After forgetting what `else` does in `try/else` and `for/else` numerous times, I have mentally aliased it with `noexcept` and `nobreak` in those respective contexts. Personally I find it to be such an unfortunate overloading of the word that I try to avoid using it if I can, as it forces people reading code to wonder "what does this thing do again?" Usually a flag, a `continue` or `break` statement can relay what I'm trying to express with few extra lines, but certainly more clarity (if the popularity of the question is any indication). – Michael Ekoka Oct 07 '20 at 16:30
23 Answers
The statements in the else
block are executed if execution falls off the bottom of the try
- if there was no exception. Honestly, I've never found a need.
However, Handling Exceptions notes:
The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.
So, if you have a method that could, for example, throw an IOError
, and you want to catch exceptions it raises, but there's something else you want to do if the first operation succeeds, and you don't want to catch an IOError from that operation, you might write something like this:
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()
If you just put another_operation_that_can_throw_ioerror()
after operation_that_can_throw_ioerror
, the except
would catch the second call's errors. And if you put it after the whole try
block, it'll always be run, and not until after the finally
. The else
lets you make sure
- the second operation's only run if there's no exception,
- it's run before the
finally
block, and - any
IOError
s it raises aren't caught here

- 25,404
- 19
- 49
- 81

- 233,004
- 25
- 132
- 111
-
11Also keep in mind that variables used in the try-block CAN be used in the else-block, so you should alway consider using this variant if you don't expect more exceptions in the else-block – WorldSEnder Aug 06 '14 at 11:56
-
4That doesn't matter, because try-scoped variables are seen outside of the try whether there's an else or not. – Reinderien Aug 30 '14 at 14:19
-
63There's no such thing as a "try-scoped variable". In Python, variable scopes are established only by modules, functions and comprehensions, not control structures. – mhsmith Apr 11 '15 at 12:59
-
11The else clause lets you write code that only makes sense if an exception wasn't thrown; the except clause can simply pass. If you put the logic in the try block, you risk silently hiding bugs in your code. Never squash exceptions you didn't expect. – Alice Purcell Apr 17 '15 at 21:54
-
Actually my customer asked to log if the execution of a function was successful or not. In this case, `else` is very useful. – Marco Sulla Oct 15 '15 at 15:51
-
@BlairConrad : Why shouldn't we simply put something_we_always_need_to_do() inside the else: part ? – vivekanon Oct 24 '15 at 20:14
-
@mystikacid because the else clause is only executed if no exception was raised – Blair Conrad Oct 25 '15 at 02:14
-
9it is not clear from this answer what the *"falls off the bottom"* means - not only does this happen because of an exception but also, because of a `return`, `continue` or `break`. – Antti Haapala -- Слава Україні Mar 03 '16 at 15:29
-
Actually, an error in the `else` block will be caught. Consider this... `try: x = 0` `except: print('foo')` `else: y = 1/0` `finally: print('bar')` Is there a way to suppress the division by zero error? – visitor Sep 03 '17 at 04:12
-
I have a use in django, when trying to search if a user with specified email exists: `try:` `user = User.objects.get(email=email)` `except User.DoesNotExist:` `user = User.objects.create_user(username=username, email=email, password=password)` `else:` `agent = Agent.objects.get(user=user) agent.is_active = True agent.save()` – MiniYuuzhan Feb 05 '18 at 06:53
-
-
If you want to play with the code from Blair Conrad go https://repl.it/@RuiCar/try-else – Rui Carvalho Jul 30 '19 at 16:30
-
1So you're telling me it's the same as not using the "else"... I say don't use it. Everyone who encounters try-else looks it up. Exception handling is the last place you want to play these games. – sudo Aug 28 '19 at 00:25
-
`else` essentially runs *after* the `try` block (if no exception occurs), but still *before* the `finally` block, which makes it different from either additional code at the end of the `try` block or code following the entire statement. (What I wonder is, why can't you have an `else` clause without any preceding `except` clause?) – chepner Jun 01 '21 at 11:26
-
@chepner, when you have no `except` clause, the `else` clause is exactly identical to putting it at the end of the `try` block. Unless you are putting that else with a except in mind (which you will write in future), it makes no sense. – Sriram Nov 21 '21 at 14:21
-
@Sriram Not if you also have a `finally` clause: the `finally` clause will execute *after* `else`, but *before* the code following the entire `try` statement. – chepner Nov 21 '21 at 17:05
-
@chepner By "at the end of the `try` block" I meant putting whatever you were going to put in the `else` clause, inside `try` itself (equivalent to just commenting out the `else:` line). This will execute after your original `try` and before `finally`. – Sriram Nov 22 '21 at 16:58
-
@Sriram But that code itself could raise an exception, which you may not want to catch or handle with the same code as the original code being `try`ed. – chepner Nov 22 '21 at 18:06
-
@chepner But you had originally asked in a case where there aren't any `except` clauses to catch errors in the first place. Think of `else` as a child of `except`, not the original `try`. – Sriram Nov 22 '21 at 18:51
-
so from this answer, it seems like the `else` clause is totally not needed if you're not using the `finally` statement. Without `finally` statement one could just write whatever they need to write, outside the `try/except` clause. Would that be correct? – tikej Aug 28 '23 at 14:31
There is one big reason to use else
- style and readability. It's generally a good idea to keep code that can cause exceptions near the code that deals with them. For example, compare these:
try:
from EasyDialogs import AskPassword
# 20 other lines
getpass = AskPassword
except ImportError:
getpass = default_getpass
and
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
else:
# 20 other lines
getpass = AskPassword
The second one is good when the except
can't return early, or re-throw the exception. If possible, I would have written:
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
return False # or throw Exception('something more descriptive')
# 20 other lines
getpass = AskPassword
Note: Answer copied from recently-posted duplicate here, hence all this "AskPassword" stuff.
Python try-else
What is the intended use of the optional
else
clause of the try statement?
The intended use is to have a context for more code to run if there were no exceptions where it was expected to be handled.
This context avoids accidentally handling errors you did not expect.
But it's important to understand the precise conditions that cause the else clause to run, because return
, continue
, and break
can interrupt the control flow to else
.
In Summary
The else
statement runs if there are no exceptions and if not interrupted by a return
, continue
, or break
statement.
The other answers miss that last part.
The optional
else
clause is executed if and when control flows off the end of thetry
clause.*
(Bolding added.) And the footnote reads:
*Currently, control “flows off the end” except in the case of an exception or the execution of a
return
,continue
, orbreak
statement.
It does require at least one preceding except clause (see the grammar). So it really isn't "try-else," it's "try-except-else(-finally)," with the else
(and finally
) being optional.
The Python Tutorial elaborates on the intended usage:
The try ... except statement has an optional else clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example:
for arg in sys.argv[1:]: try: f = open(arg, 'r') except OSError: print('cannot open', arg) else: print(arg, 'has', len(f.readlines()), 'lines') f.close()
The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.
Example differentiating else
versus code following the try
block
If you handle an error, the else
block will not run. For example:
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!
And now,
>>> handle_error()
handled a RuntimeError, no big deal.
And now we have left the try block!

- 374,368
- 89
- 403
- 331
-
2main point from the docs: "The use of the `else` clause is better than adding additional code to the `try` clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the `try ... except` statement." – starriet Dec 12 '21 at 05:33
-
-
@starriet comment is clear and concise. Just wanted to highlight since this comment adds to this (already good) answer. – Elysiumplain Oct 06 '22 at 00:37
-
The example with the f=open() would explain more (at least to me) if the f.close() statement is in a "finally:" block. – user3481644 Feb 25 '23 at 14:34
-
That is an example quoted from the documentation - I'd rather present it as is... – Russia Must Remove Putin Feb 25 '23 at 17:16
One use: test some code that should raise an exception.
try:
this_should_raise_TypeError()
except TypeError:
pass
except:
assert False, "Raised the wrong exception type"
else:
assert False, "Didn't raise any exception"
(This code should be abstracted into a more generic test in practice.)

- 14,921
- 5
- 53
- 53
Try-except-else is great for combining the EAFP pattern with duck-typing:
try:
cs = x.cleanupSet
except AttributeError:
pass
else:
for v in cs:
v.cleanup()
You might think this naïve code is fine:
try:
for v in x.cleanupSet:
v.clenaup()
except AttributeError:
pass
This is a great way of accidentally hiding severe bugs in your code. I typo-ed cleanup
there, but the AttributeError
that would let me know is being swallowed. Worse, what if I'd written it correctly, but the cleanup method was occasionally being passed a user type that had a misnamed attribute, causing it to silently fail half-way through and leave a file unclosed? Good luck debugging that one.

- 4,543
- 5
- 22
- 49

- 12,622
- 6
- 51
- 57
I find it really useful when you've got cleanup to do that has to be done even if there's an exception:
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()

- 57,944
- 17
- 167
- 143

- 6,330
- 3
- 35
- 52
-
This is IMHO the best representation, an example using file I/O (shown somewhere above) illustrates this quite well. Basically, else: takes code out of the try: block and executes it before finally: if there was no exception, such as failing to open a file. – user3481644 Feb 25 '23 at 14:39
Even though you can't think of a use of it right now, you can bet there has to be a use for it. Here is an unimaginative sample:
With else
:
a = [1,2,3]
try:
something = a[2]
except IndexError:
print("out of bounds")
else:
print(something)
Without else
:
try:
something = a[2]
except IndexError:
print("out of bounds")
if "something" in locals():
print(something)
Here you have the variable something
defined if no error is thrown. You can remove this outside the try
block, but then it requires some messy detection if a variable is defined.
-
6What's wrong with `something = a[2]; print something` inside the try: block? – S.Lott May 13 '09 at 02:28
-
@ S.Lott nothing, but what if someone is sending you a list, and you don't want to display the data if its not long enough because it is probably corrupted? – Unknown May 13 '09 at 02:32
-
14S. Lott: 'print something' could raise a different exception that you don't want to intercept. – Darius Bacon May 13 '09 at 05:38
-
I don't see the difference. If I get an out of bounds exception, it prints "out of bounds". Got that. If I get some other exception, it's uncaught by this block of code. If I get no exception, the behavior is to print the value of something, which is a[2]. I don't see what the else does in this example. – S.Lott May 13 '09 at 18:21
-
3The value of 'something', when printed, might raise the error in its __str__() method. While that value is actually just 2 in this example, you might just as well point out that there is no out-of-bounds exception here either. – Darius Bacon May 14 '09 at 06:30
-
For this (hypothetical) example, I would just put `something = 'out of bound'` in the except block so that `print(something)` would always print the correct response ;-) – wovano Nov 16 '22 at 12:43
There's a nice example of try-else
in PEP 380. Basically, it comes down to doing different exception handling in different parts of the algorithm.
It's something like this:
try:
do_init_stuff()
except:
handle_init_suff_execption()
else:
try:
do_middle_stuff()
except:
handle_middle_stuff_exception()
This allows you to write the exception handling code nearer to where the exception occurs.

- 28,822
- 30
- 126
- 171
From Errors and Exceptions # Handling exceptions - docs.python.org
The
try ... except
statement has an optionalelse
clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example: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()
The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.

- 275,237
- 103
- 548
- 598
try:
statements # statements that can raise exceptions
except:
statements # statements that will be executed to handle exceptions
else:
statements # statements that will be executed if there is no exception
Example :
try:
age=int(input('Enter your age: '))
except:
print ('You have entered an invalid value.')
else:
if age <= 21:
print('You are not allowed to enter, you are too young.')
else:
print('Welcome, you are old enough.')
The Output :
>>>
Enter your age: a
You have entered an invalid value.
>>> RESTART
>>>
Enter your age: 25
Welcome, you are old enough.
>>> RESTART
>>>
Enter your age: 13
You are not allowed to enter, you are too young.
>>>
Copied from : https://geek-university.com/python/the-try-except-else-statements/

- 13,789
- 3
- 29
- 54

- 1,864
- 21
- 23
Looking at Python reference it seems that else
is executed after try
when there's no exception.
The optional else clause is executed if and when control flows off the end of the try clause. 2 Exceptions in the else clause are not handled by the preceding except clauses.
Dive into python has an example where, if I understand correctly, in try
block they try to import a module, when that fails you get exception and bind default but when it works you have an option to go into else
block and bind what is required (see link for the example and explanation).
If you tried to do work in catch
block it might throw another exception - I guess that's where the else
block comes handy.
-
"The optional else clause is executed if and when control flows off the end of the try clause" is another difference, since you can return out of the `try` block. – Tomer W Mar 20 '18 at 21:14
I would add another use case that seems straight forward when handling DB sessions:
# 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()

- 386
- 3
- 9
-
Interesting - I know session.close() will be executed before the return, but will the session.commit() be executed? Does python recognize the "return" and delay that until else: and finally: are executed? – user3481644 Feb 25 '23 at 14:43
-
@user3481644 The order of execution would be: - try block - except block (in case of exception) - else block (in case no exception) - finally block at the end – vadimbog Feb 27 '23 at 14:40
That's it. The 'else' block of a try-except clause exists for code that runs when (and only when) the tried operation succeeds. It can be used, and it can be abused.
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
Personally, I like it and use it when appropriate. It semantically groups statements.

- 92,761
- 29
- 141
- 204
Here is another place where I like to use this pattern:
while data in items:
try
data = json.loads(data)
except ValueError as e:
log error
else:
# work on the `data`
-
1You can just use ``continue`` instead – the "break out early" pattern. This allows you to drop the "else" clause and its indentation, making the code easier to read. – malthe Jun 09 '16 at 09:46
I have found the try: ... else:
construct useful in the situation where you are running database queries and logging the results of those queries to a separate database of the same flavour/type. Let's say I have lots of worker threads all handling database queries submitted to a queue
#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
Of course if you can distinguish between the possible exceptions that might be thrown, you don't have to use this, but if code reacting to a successful piece of code might throw the same exception as the successful piece, and you can't just let the second possible exception go, or return immediately on success (which would kill the thread in my case), then this does come in handy.

- 2,187
- 2
- 18
- 28
Perhaps a use might be:
#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()
Maybe this will lead you too a use.

- 5,393
- 1
- 25
- 20
I have found else
useful for dealing with a possibly incorrect config file:
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
An exception reading the lock
config disables lock monitoring and ValueErrors log a helpful warning message.

- 1,518
- 12
- 26
Suppose your programming logic depends on whether a dictionary has an entry with a given key. You can test the result of dict.get(key)
using if... else...
construct, or you can do:
try:
val = dic[key]
except KeyError:
do_some_stuff()
else:
do_some_stuff_with_val(val)

- 51
- 5
One of the use scenarios I can think of is unpredictable exceptions, which can be circumvented if you try again. For instance, when the operations in try block involves random numbers:
while True:
try:
r = random.random()
some_operation_that_fails_for_specific_r(r)
except Exception:
continue
else:
break
But if the exception can be predicted, you should always choose validation beforehand over an exception. However, not everything can be predicted, so this code pattern has its place.

- 17,361
- 24
- 78
- 126
-
1You can do this putting the `break` inside the `try` at the end, which is cleaner IMO, and you don't need the `else`. Also the `continue` is not really needed, you can just `pass`. – Dirbaio Jun 10 '17 at 17:44
An else
block can often exist to complement functionality that occurs in every except
block.
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.
"""
In this case, inconsistency_type
is set in each except block, so that behaviour is complemented in the no-error case in else
.
Of course, I'm describing this as a pattern that may turn up in your own code someday. In this specific case, you just set inconsistency_type
to 0 before the try
block anyway.

- 10,652
- 4
- 37
- 52
One could use this construct for handling exceptions in a common way within the finally
clause, while doing something else when there's no exception:
class TooManyRetries(RuntimeError):
pass
n_tries = 0
max_retries = 2
while True:
try:
n_tries += 1
if n_tries >= max_retries:
raise TooManyRetries
fail_prone_operation()
except Exception1 as ex:
# handle1
except Exception2 as ex:
# handle2
except Exception3 as ex:
# handle3
except TooManyRetries as ex:
raise
else: # No exception
n_tries = 0
finally:
common_restore_state()
continue

- 23,452
- 27
- 113
- 201
I may have missed it in the dozens of answers, but I prefer to minimize the LOC in a try: block, but I like how finally: can clean up a code segment. The else: block provides a clean way to accommodate that for file I/O, database work, etc., lots of examples above.

- 398
- 2
- 12
The else:
block is confusing and (nearly) useless. It's also part of the for
and while
statements.
Actually, even on an if
-statement, the else:
can be abused in truly terrible ways creating bugs that are very hard to find.
Consider this.
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
Think twice about else:
. It is generally a problem. Avoid it except in an if
-statement and even then consider documenting the else
- condition to make it explicit.

- 384,516
- 81
- 508
- 779
-
6I would disagree with this one. In "if-elif" block, "else" is used as "default" would be used in "case" block of C language. It is always recommended to handle "default" case even if you think you've covered all cases in various conditions. – Josip May 13 '09 at 08:40
-
1@Josip: used as a "default" can be confusing. The issue is to clearly define the condition that is this "default". A poorly-defined default condition can be the root cause of buggy behavior. Else can be a cause of confusion. It should be thought through very carefully in all cases, not just try, for and while, but if as well. – S.Lott May 13 '09 at 09:47
-
5Well, the above code is totally abstract and doesn't do anything meaningful, so yea - no wonder it is confusing. – julx Jun 03 '11 at 11:29
-
@julkiewicz: The code is, sadly, very typical of a misused `else`. I read a lot of code. I've see this a lot. What -- exactly -- is true for the `else`? It's rather hard to define correctly? – S.Lott Jun 03 '11 at 11:46
-
1Sure this looks suspecious. It's just that for me it's not because of the `else` clause itself but because of the peculiar selection of conditions. You can write buggy code using whatever constructs you want pretty easily. It's not the constructs to blame. – julx Jun 03 '11 at 13:53
-
@julkiewicz: "It's not the constructs to blame". My point is that this is false. If the `else` where not a part of the language, then the logic would have to be made absolutely explicit. It would reduce the bugginess considerably by eliminating all guess-work on the part of you or I to try and determine of the `else` condition makes sense in the overall algorithm. There's no place for guess-work or deduction. – S.Lott Jun 03 '11 at 13:56
-
2@S.Lott "It would reduce bugginess" - and my point is that this is false. I think we just have a genuine difference in opinions. Bad programmers always find ways to write buggy programs. Always. Good programmers always seek good practices and can write good code in just about any language. Eliminating useful constructs just gives less power to the good programmers while not particularily helping out the bad ones as those are capable of inventing an infinite number of ways to f**k things up. – julx Jun 03 '11 at 17:40
-
7Consider: `if x > 0: return "yes"` and `if x <= 0: return "no"`. Now a person comes and changes one of the conditions to say `x > 1` but forgets to change the other one. How is that reducing number of bugs that would be committed. `if else` clauses are sometimes many lines apart. DRY is a good practice, much more often than not, really. (sorry for the double post). – julx Jun 03 '11 at 17:47
-
@julkiewicz: If -- in your example -- a condition was omitted, it was omitted explicitly. It requires little guess-work to read the `if` and `elif` blocks to prove that a condition was missing. If we guess at the `else` block, we don't have any clear statement of the author's original design. Just our personal guess. It's hard to compare our guess as to the `else` condition with the author's, since the author left us no hint in the code. – S.Lott Jun 03 '11 at 18:37
-
I agree the `else` clause promotes less stringent efforts to account for all possible conditions. However I also propose that there are few actual real genii and therefore humans do miss conditions, even genii. I find the `else` clause a nice debug tool. If you have superpowers that catch all conditions everytime in your coding, perhaps you(noone in particular) can enjoy coding in C++ with all that lovely puncuation that stringent programmers never stumble on (or do they?). So my point is the use case is not if `else` promotes sloppiness, but if it deals with imperfection of human coders. – DevPlayer Oct 04 '11 at 03:13
-
@DevPlayer: The imperfections in human coders are found **specifically** by avoiding `else` and dealing with the logic failures that show up. No one is a genius. Sloppy use of `else` makes it even harder to be sure things are right. Avoiding `else` puts your human mistakes in your human face so you can fix them. Not hope that something good happened. The point is to have as many debugging tools (and diagnostic tools and human-imperfection detections) as possible. Not **hope** that things will wok even when we stumble. – S.Lott Oct 04 '11 at 23:58
-
I agree with you @S.Lott that having debugging tools is a gain. I find the `else` clause a usable debugging tool. And I agree that using the `else` clause in some emotional **hope** is less logical then "dealing" with logic failures. However I disagree with that imperfections in human codes are found **specifically** by avoiding `else` clauses. It **may** help but it also **may** lead you to a false sense that you've avoided logic errors by omitting the `else`. Many mistakes go hidden simply because a test condition may be rarely encountered. Such rare occurances are not in one's face. – DevPlayer Oct 07 '11 at 05:29
-
@DevPlayer: "it also may lead you to a false sense that you've avoided logic errors" Unlikely. Using `else: raise Exception('Logic Error')` is not a false sense of security. It's a real failure that really happens and really reveals a logic error. If your unit testing is not complete enough to find the logic error, then, production use will find it someday. Using a lazy -- traditional -- "else-with-implied-condition" will not ever fail (even in production) and the logic error will remain hidden forever as a "weirdness" in the application. – S.Lott Oct 07 '11 at 09:43
-
1For my money, worse than using `else` is `if a < 10`. The example given by @S.Lott is a 'straw man' for blaming `else`. What are `a` and `b`? As soon as you write `if batch_size < 10 ... elif batch_size >= 10 and job_size > 3 ... else ...` you know what you're reasoning about and there are fewer problems with `else`. Better still is to encapsulate the two conditions into variable names: `is_small_batch = a < 10 ... is_huge_batch = a >= 10 and b > 3 ... if is_small_batch: ... elif is_huge_batch: ... else ...`. Other improvements, of course, are possible, some completely removing `else`. – Nic Sep 16 '18 at 21:53
-
1you might, for example, use the chain of responsibility pattern https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern but this is a sledgehammer to crack a walnut in many small cases. I have seen chain of responsibility make simple code obscure. IMO `else` can be completely appropriate in a well-defined case, and the `try...except...else` can occasionally express a problem more simply, eloquently and explicitly than any other structure. – Nic Sep 16 '18 at 22:10
-
2You are totally off topic and 'else' is meant for executing logic that does not hold true for the conditions. – Edwin Feb 19 '19 at 02:21