x = 10
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: 1021 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
tryclause, all statements are executed until an exception is encountered. exceptis used to catch and handle the exception(s) that are encountered in the try clause.elselets you code sections that should run only when no exceptions are encountered in the try clause.finallyenables 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:
pass21.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 executedtry:
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 executed21.5.2 Ex: Int & Float
def get_int(x):
try:
return int(x)
except ValueError:
print(f"'{x}' is not a number")get_int(5)
#> 5
get_int(-1)
#> -1
get_int(5.6)
#> 5
get_int("cat")
#> 'cat' is not a numberdef attempt_float(x):
try:
return float(x)
except ValueError:
return xattempt_float("2")
#> 2.0
attempt_float("X")
#> 'X'using pass to return NoneType and not print anything
def get_int2(x):
try:
return int(x)
except ValueError:
passget_int2(2)
#> 2
get_int2("Cat") # Nothing
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()
#> False21.5.3 Ex: Try open file
try:
with open('file.log') as file:
read_data = file.read()
except:
print('Could not open file.log')
#> Could not open file.logtry:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
#> [Errno 2] No such file or directory: 'file.log'try:
linux_interaction() # <-- AssertionError trigger in this line
with open('file.log') as file:
read_data = file.read()
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 executedtry:
mac_interaction()
with open('file.log') as file: # <-- FileNotFoundError trigger in this line
read_data = file.read()
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.
nobles = {'He': 2, 'Ne': 10, 'Ar': 18, 'Kr': 36, 'Xe': 54}
def show_element_info(elements):
for element in elements:
print('Atomic number of {} is {}'.format(
element, nobles[element]))try:
show_element_info(['Ne', 'Ar', 'Br'])
except KeyError as err:
missing_element = err.args[0]
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: Br21.6.2 Simple Logging
import logging
UPLOAD_ROOT = "fold/testdir"
def create_upload_dir(username):
userdir = os.path.join(UPLOAD_ROOT, username)
try:
os.makedirs(userdir)
except FileExistsError as err:
logging.error("Upload dir already exists: %s",
err.filename)create_upload_dir("testuser")
#> NameError: name 'os' is not defined. Did you forget to import 'os'21.7 else clause
try:
mac_interaction() # Pass
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:
read_data = file.read()
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
f = open(path, mode="w")
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):
passraise MyCustomException('A custom message for my custom exception')
#> MyCustomException: A custom message for my custom exceptiontry:
raise MyCustomException('A custom message for my custom exception')
except MyCustomException:
print('My custom exception was raised')
#> My custom exception was raised21.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:
x = get_number()
except:
logging.exception('Caught an error')
#> 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'