= 10
x if x > 5:
raise Exception('x should not exceed 5. The value of x was: {}'.format(x))
#> Exception: x should not exceed 5. The value of x was: 10
21 Exception
raise
: allows you to throw an exception at any time.assert
: enables you to verify if a certain condition is met and throw an exception if it isn’t.- In the
try
clause, all statements are executed until an exception is encountered. except
is used to catch and handle the exception(s) that are encountered in the try clause.else
lets you code sections that should run only when no exceptions are encountered in the try clause.finally
enables you to execute sections of code that should always run, with or without any previously encountered exceptions.
21.1 Concept
- put as little code as possible in the try block. You do this so your except block(s) will not catch or mask errors that they should not.
21.2 Anti-pattern
Don’t ever do this:
try:
do_something()except:
pass
21.3 Raising Exception
21.4 AssertionError
Exception
import sys
assert ('linux' in sys.platform), "This code runs on Linux only."
#> AssertionError: This code runs on Linux only.
21.5 try
and except
Block
Python executes code following the try
statement as a “normal” part of the program. The code that follows the except
statement is the program’s response to any exceptions in the preceding try
clause.
21.5.1 Ex: Linux function
def linux_interaction():
assert ('linux' in sys.platform), "Function can only run on Linux systems."
print('Doing something.')
def mac_interaction():
assert ('darwin' in sys.platform), "Function can only run on MacOS systems."
print('Doing something.')
try:
linux_interaction()except:
print('Linux function was not executed')
#> Linux function was not executed
try:
linux_interaction()except AssertionError as error:
print(error)
print('The linux_interaction() function was not executed')
#> Function can only run on Linux systems.
#> The linux_interaction() function was not executed
21.5.2 Ex: Int & Float
def get_int(x):
try:
return int(x)
except ValueError:
print(f"'{x}' is not a number")
5)
get_int(#> 5
-1)
get_int(#> -1
5.6)
get_int(#> 5
"cat")
get_int(#> 'cat' is not a number
def attempt_float(x):
try:
return float(x)
except ValueError:
return x
"2")
attempt_float(#> 2.0
"X")
attempt_float(#> 'X'
using pass
to return NoneType
and not print anything
def get_int2(x):
try:
return int(x)
except ValueError:
pass
2)
get_int2(#> 2
"Cat") # Nothing
get_int2(
type(get_int2("Cat"))
#> <class 'NoneType'>
isnumeric()
to check whether string is all numeric. But, it’s not very effective:
"123".isnumeric() # Only case that works
#> True
"12.3".isnumeric()
#> False
"-1".isnumeric()
#> False
"cat".isnumeric()
#> False
21.5.3 Ex: Try open file
try:
with open('file.log') as file:
= file.read()
read_data except:
print('Could not open file.log')
#> Could not open file.log
try:
with open('file.log') as file:
= file.read()
read_data except FileNotFoundError as fnf_error:
print(fnf_error)
#> [Errno 2] No such file or directory: 'file.log'
try:
# <-- AssertionError trigger in this line
linux_interaction() with open('file.log') as file:
= file.read()
read_data except FileNotFoundError as fnf_error:
print(fnf_error)
except AssertionError as error:
print(error)
print('Linux linux_interaction() function was not executed')
#> Function can only run on Linux systems.
#> Linux linux_interaction() function was not executed
try:
mac_interaction()with open('file.log') as file: # <-- FileNotFoundError trigger in this line
= file.read()
read_data except FileNotFoundError as fnf_error:
print(fnf_error)
except AssertionError as error:
print(error)
print('Linux mac_interaction() function was not executed')
#> Doing something.
#> [Errno 2] No such file or directory: 'file.log'
21.6 try
and except
catch error
21.6.1 Ex: Atomic numbers of noble gases.
= {'He': 2, 'Ne': 10, 'Ar': 18, 'Kr': 36, 'Xe': 54}
nobles
def show_element_info(elements):
for element in elements:
print('Atomic number of {} is {}'.format(
element, nobles[element]))
try:
'Ne', 'Ar', 'Br'])
show_element_info([except KeyError as err:
= err.args[0]
missing_element print(f"Error args: {err.args}")
print(f"Missing data for element: {missing_element}")
#> Atomic number of Ne is 10
#> Atomic number of Ar is 18
#> Error args: ('Br',)
#> Missing data for element: Br
21.6.2 Simple Logging
import logging
= "fold/testdir"
UPLOAD_ROOT
def create_upload_dir(username):
= os.path.join(UPLOAD_ROOT, username)
userdir try:
os.makedirs(userdir)except FileExistsError as err:
"Upload dir already exists: %s",
logging.error( err.filename)
"testuser")
create_upload_dir(#> NameError: name 'os' is not defined. Did you forget to import 'os'
21.7 else
clause
try:
# Pass
mac_interaction() except AssertionError as error:
print(error)
else:
print('Executing the else clause.')
#> Doing something.
#> Executing the else clause.
21.7.1 try-except-else-finally
try:
mac_interaction()except AssertionError as error:
print(error)
else:
try:
with open('file.log') as file:
= file.read()
read_data except FileNotFoundError as fnf_error:
print(fnf_error)
finally:
print('Cleaning up, irrespective of any exceptions.')
#> Doing something.
#> [Errno 2] No such file or directory: 'file.log'
#> Cleaning up, irrespective of any exceptions.
21.7.2 Always close File
= open(path, mode="w")
f
try:
write_to_file(f)except:
print("Failed")
else:
print("Succeeded")
finally:
f.close()
21.8 Custom Exception
Custom exceptions initialize by creating a class that inherits from the base Exception
class of Python
class MyCustomException(Exception):
pass
raise MyCustomException('A custom message for my custom exception')
#> MyCustomException: A custom message for my custom exception
try:
raise MyCustomException('A custom message for my custom exception')
except MyCustomException:
print('My custom exception was raised')
#> My custom exception was raised
21.9 Full stack trace by logging
Python provides an easy way to capture that error event, and all the information you need to fix it. The logging module has a function called exception()
, which will log your message along with the full stack trace of the current exception. So you can write code like this:
import logging
def get_number():
return int('foo')
try:
= get_number()
x except:
'Caught an error')
logging.exception(#> ERROR:root:Caught an error
#> Traceback (most recent call last):
#> File "<string>", line 3, in <module>
#> File "<string>", line 3, in get_number
#> ValueError: invalid literal for int() with base 10: 'foo'