python exception assertion - ghdrako/doc_snipets GitHub Wiki
There are 64 build-in exception. it's three shape hierarchy.
General exception can handle a raised exception as long as is matches coverage, concrete exception is not reqired.
try:
1/0
except AritmeticError: # ZeroDivisionError
...
try:
# code that might raise an exception
except Exception as e:
# code that executes if an exception occurs
else:
# code that executes if no exception occurs (optional)
finally:
# code that executes whether an exception occurs or not (optional)
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
try:
1 / 0
except ZeroDivisionError as ex:
print(f"Type: {type(ex)}")
print(f"Is an instance of ZeroDivisionError? {isinstance(ex, ZeroDivisionError)}")
Raising exception
The rise
instruction raises the specified exception as if it was rised in normal(natural) way.
try:
rise ZeroDivisionError
except AritmeticError:
...
def range_check_user_input(value):
if not 0 < value <= 100:
raise ValueError("value range exceeded", value)
# additional functionality
def get_data_from_user():
# initialization and gather user input
try:
range_check_user_input(value)
except ValueError as e:
print(e)
# restart code to get user input
To supply a custom message to the exception, we use the format raise ExceptionClass("custom message") . A few examples follow:
raise ValueError("Please use the correct parameter.")
# ERROR: ValueError: Please use the correct parameter.
code_used = "3#"
raise ValueError(f"You used a wrong parameter: {code_used!r}")
# ERROR: ValueError: You used a wrong parameter: '3#'
Re-rise exception
Empty rise can only be used in except block. In folowing code ZeroDivisionError is rised twice.
def division(n):
try:
return 0/n
except:
print('error')
raise
try:
division(1)
except AritmeticError:
print("not ok")
Output:
error
not ok
Handle multiple exception
try:
...
except ZeroDivisionError as e:
print(e)
print(type(e))
except IndexError as e:
print(e)
print(type(e))
try:
...
except (ZeroDivisionError, IndexError) as e:
print(e)
print(type(e))
Assertion
import math
data = float(input("Enter number:"))
assert data > 2.0 # this rise AssertionError if condition is not true
x = math.sqrt(data)
print(x)
All assert statements will actually be removed from your code automatically when the interpreter is run with the -O
or -OO
flags to optimize the bytecode.
Asserts in Python are mainly meant to be used in tests and only during development phase just to ensure that things are not deviating from what is being expected e.g. that functions return sane values and that state variables do not contradict each other, and similar conditions. Also asserts are meant to fail early (in the spot where the error was detected) and thus AssertErrors
are not really meant to be captured or handled programmatically.
else
def access(val):
try:
element=[1,2,3]
element[val]
except IndexError:
print("Index error")
return val
else:
print("ok")
return val
print(acces(0))
print(acces(5))
Import exception
try
import file
except ImportError IE:
print(IE.name)
print(IE.path)
Encoding exception
try:
b'\x99'.decode("utf-8")
except UnicodeError as UE:
print(UE.encoding) # utf-8
print(UE.reason) # invalid start byte
print(UE.object) # b'\x99'
print(UE.start) # 0
print(UE.end) # 1
Chained exceptions
__context__
__casuse__
data=['first',2]
try:
print(data[2]
except Exception as EX:
try:
print(1/0)
except ZeroDivisionError as Z:
print(EX)
print(Z)
print(Z.__context__)
print(Z.__cause__)
__traceback__
- https://docs.python.org/3/library/traceback.html
- https://realpython.com/python-traceback/
- https://pymotw.com/2/traceback/
Defining custom exception classes
class FileExtensionError(TaskierError):
def __init__(self, file_path):
super().__init__()
self.file_path = file_path
def __str__(self):
return f"The file ({self.file_path}) doesn't appear to be a CSV file."
# In another part of our package
from pathlib import Path
def upload_file(file_path):
path = Path(file_path)
if path.suffix.lower() != ".csv":
raise FileExtensionError(file_path)
else:
print(f"Processing the file at {file_path}")
class MyException(Exception):
def __init__(self,msg):
self.message = msg
balance = 1000
def insufficientBalance(withdrawal_amount):
if withdrawal_amount <= balance:
print('withdrawal successful')
else:
rise MyException('Widrawal amount is greater then balance')
amount = int(input('Enter the widrawal amount:')
try:
insufficientBalance(amount)
exception MyException as obj:
print(obj)
logging exception message
Logging an exception in python with an error can be done in the logging.exception()
method. This function logs a message with level ERROR on this logger. The arguments are interpreted as for debug(). Exception info is added to the logging message. This method should only be called from an exception handler.
import logging
try:
printf("GeeksforGeeks")
except Exception as Argument:
logging.exception("Error occurred while printing GeeksforGeeks")
try:
main_loop()
except Exception:
logger.exception("Fatal error in main loop")
By default, logger.exception uses the log level of ERROR. Alternatively, you can use the regular logging methods— logger.debug(), logger.info(), logger.warn(), etc.—and pass the exc_info parameter, setting it to True:
while True:
try:
main_loop()
except Exception:
logger.error("Fatal error in main loop", exc_info=True)
Setting exc_info
to True
will cause the logging to include the full stack trace…. exactly like logger.exception() does. The only difference is that you can easily change the log level to something other than error: Just replace logger.error with logger.warn, for example.