Implementing a Python decorator for enforcing type checking on function arguments
Write a Python program that implements a decorator to enforce type checking on the arguments of a function.
Sample Solution:
Python Code:
import inspect
def enforce_type_checking(func):
def wrapper(*args, **kwargs):
# Get the function signature and parameter names
signature = inspect.signature(func)
parameters = signature.parameters
# Iterate over the positional arguments
for i, arg in enumerate(args):
param_name = list(parameters.keys())[i]
param_type = parameters[param_name].annotation
if not isinstance(arg, param_type):
raise TypeError(f"Argument '{param_name}' must be of type '{param_type.__name__}'")
# Iterate over the keyword arguments
for param_name, arg in kwargs.items():
param_type = parameters[param_name].annotation
if not isinstance(arg, param_type):
raise TypeError(f"Argument '{param_name}' must be of type '{param_type.__name__}'")
# Call the original function
return func(*args, **kwargs)
return wrapper
# Example usage
@enforce_type_checking
def multiply_numbers(x: int, y: int) -> int:
return x * y
# Call the decorated function
result = multiply_numbers(5, 7) # No type errors, returns 30
print("Result:", result)
result = multiply_numbers("5", 7) # Type error: 'x' must be of type 'int'
Sample Output:
Result: 35 Traceback (most recent call last): File h:\anaconda3\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec exec(code, globals, locals) File c:\users\me\.spyder-py3\history_internal.py:35 result = multiply_numbers("5", 7) # Type error: 'x' must be of type 'int' File c:\users\me\.spyder-py3\history_internal.py:13 in wrapper raise TypeError(f"Argument '{param_name}' must be of type '{param_type.__name__}'") TypeError: Argument 'x' must be of type 'int'
Explanation:
In the above exercise, the 'enforce_type_checking' decorator is defined. It takes a function as an argument and returns a wrapper function that checks the type on the arguments. The wrapper function inspects the function's signature using inspect.signature to get the parameter names and their annotations. It then iterates over the positional and keyword arguments, checking their types against the corresponding parameter annotations. It raises a TypeError if the types do not match.
Flowchart:
Have another way to solve this solution? Contribute your code (and comments) through Disqus.
Previous: Implementing a Python decorator for exception handling with a default response.
Next: Implementing a Python decorator to measure memory usage of a function.
What is the difficulty level of this exercise?
Test your Programming skills with w3resource's quiz.
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics