Flow-control structures: Difference between revisions

Line 323:
print "No odd factors found"
</python>
In addition, as shown in the foregoing example, Python loops support an ''else:'' suite which can be used to handle cases when the loop was intended to search for something, where the code would break out of the loop upon finding its target. In that situation the ''else:'' suite can be used to handle the failure. (In most other languages one is forced to use a "sentinel value" or a special flag variable ... typically set to "False" before the loop and conditionally set to "True" within the loop to handle situations for which the Python ''else:'' on loops is intended).
 
===Exceptions===
<pre>
# Flow Control Structures in Python (Exceptions)
# Exceptions are handled by the following operators:
# try, except, finally, break, and continue, etc.
# See each case for details...
 
A Python exception is simply any subclass of the built-in BaseException class, or any of its descendents. User defined exception classes are normally descendents of the Exception class (which is, itself, a subclass of BaseException). To "throw" any exception (user defined or otherwise) one uses the ''raise'' statement. To capture exceptions one must enclose the code in a ''try:'' ... ''except...:'' block. Any exception listed in an except block will catch all subclasses of that exception. For example ZeroDivisionError is derived from ArithmeticError. Thus an exception clause for ArithmeticError would catch a ZeroDivisionError (or any other ArithmeticError).
import math
 
As a consequence of this one must arrange the order of exception clauses such that the more specific exceptions are listed (caught) before their more general base exceptions. Only the first matching exception clause will be executed. An except clause which lists no exceptions will catch '''all''' possible exceptions. (This is usually considered to be very poor programming practice because it can hide unintended coding errors).
 
An exception can be re-raised by simply calling the ''raise'' statement without any arguments (from within any exception handler). Thus a function can catch an exception, attempt to deal with it, then, if necessary, throw it it back to the next layer out in a given call stack. Uncaught exceptions will be handled by the interpreter by terminating the program and printing an error message and stack trace.
 
def main():
</pre>
====Case 1 - Try, Except====
<prepython>
try:
temp = 0/0
# 'except' catches any errors that may have been raised between the code of 'try' and 'except'
except: # Note: catch all handler ... NOT RECOMMENDED
print "An error occurred."
# Output : "An error occurred"
</prepython>
====Case 2 - Try, Except====
<prepython>
try:
temp = 0/0
Line 352 ⟶ 350:
print "You've divided by zero!"
# Output : "You've divided by zero!"
</prepython>
====Case 3 - Try, Except, Finally====
<prepython>
try:
temp = 0/0
Line 366 ⟶ 364:
# An error occurred
# End of 'try' block...
</prepython>
 
====Case 4 - Try, Except within a function====
Note: Prior to version 2.5 a ''try:'' statement could contain either series of ''except:'' clauses '''or''' a ''finally:'' clause but '''not both.''' It was thus necessary to nest the exception handling in an enclosing ''try:''...''finally:'' loop like so:
<pre>
 
def divisionbyzero(): # create a function that is sure to fail
<python>
temp = 0/0
try:
divisionbyzero()try:
temp = 0/0 pass
except ZeroDivisionError:
except (MyException1, MyOtherException):
print "You've divided by zero!"
# Output : pass
except SomeOtherException:
# You've divided by zero!
finally:
</pre>
do_some_cleanup() # run in any case, whether any exceptions were thrown or not
====Case 5 - Try, Except, Else====
</python>
<pre>
====Case 4 - Try, Except, within a functionElse====
<python>
try:
temp = 1/1 # not a division by zero error
Line 389:
# Output :
# No apparent error occurred.
</prepython>
====Case 65 - Try, Except, break, continue====
<prepython>
i = 0
while 1: # infinite loop
Line 412:
# You've divided by zero. Decrementing i and continuing...
# Imaginary Number! Breaking out of loop
</prepython>
====Case 76 - Creating your own custom exceptions, raise====
<prepython>
# Let's call our custom error "StupidError"; it inherits from the Exception class
Line 428:
# Output :
# Something stupid occurred: Segfault
</prepython>
 
===Case 87 - continue, else in "for" loop===
<prepython>
i = 101
for i in range(0,4): # loop 4 times
print "I will always be seen."
if (i % 2) == 0:
continue # continue goes back to the loop beginning for a new iteration.
print "I'll neveronly be seen every other time."
else:
print "Loop done"
# Output:
# I will always be seen.
# I will always be seen.
# I'll only be seen every other time.
# I will always be seen.
# I will always be seen.
# I'll only be seen every other time.
# Loop done
if(__name__ == "__main__"):
main()
</prepython>
 
===The "with" statement===
{{works with|Python|2.6}}
See [[http://www.python.org/peps/pep-0343.html PEP 0343, The "with" statement]]
 
>>> with open("some_file"): # file ``some_file`` is closed after ``with`` block in any case whether an exception is raised or not
<python>
... raise Exception("an error")
class Quitting(Exception): pass
max = 10
with open("some_file") as myfile:
exit_counter = 0
for line in myfile:
exit_counter += 1
if exit_counter > max:
raise Quitting
print line,
</python>
 
The ''with'' statement allows classes to encapsulate "final" (clean-up) code which will automatically be executed regardless of exceptions that occur when working "with" these objects. Thus, for the foregoing example, the file will be closed regardless of whether it's more than 10 lines long. Many built-in and standard library classes have "context managers" which facilitate their use in ''with:'' code. In addition it's possible to define special __enter__() and __exit__() methods in one's own classes which will be implicitly called by the interpreter when an object is used within a ''with:'' statement.
 
Use cases for ''with:'' enabled objects include automated/guaranteed closing of files, release of threading lock objects, commit or rollback of database transactions, and save/restore of any desired state (such as terminal settings when using the curses module, the precision settings when using the Decimal module, or even saving and restoring ''sys.stdout'' for temporary redirection). It is a feature that seems to be unique to Python.
 
===Yield expressions===
{{works with|Python|2.5}}
Anonymous user