Importing Python code by file reference and inspecting classes
08-18-2023
I recently had a use case for importing Python code by reference to its full file path, inspecting each class found within the source, and performing a task if a particular attribute was found. This was for a command-line interface (CLI) and I wanted the script to be run like the following:
$ python inspect_source.py /full/path/to/source.py
My initial scan of stackoverflow answers didn't provide a solution for exactly what I wanted to do in this case. So I turned to my other favorite resource, Python 3 Module of the Week, and read up on the standard library's importlib and inspect modules. I was able to piece this together.
import importlib
import inspect
import sys
from pathlib import Path
source_path = sys.argv[1]
cwd = Path(__file__).parent
path = Path(source_path)
module_name = path.stem
# Append the parent of the source_path to the python path
sys.path.append(str(path.parent))
print(f"Importing {source_path} as {module_name}")
# Import the source code as a module.
imported_source = importlib.import_module(module_name)
# Use inspect to get all classes.
for name, _class in inspect.getmembers(imported_source, inspect.isclass):
# Check for existence of the target attribute.
try:
attrib = getattr(_class, "my_target_attribute")
except AttributeError:
continue
if attrib is None:
continue
else:
# If the attribute is found, do something.
print(f"{name} -- do something with the target attribute.")
This solution requires that all modules imported by the source file already exist in your environment. Otherwise you will get import errors.
I recently had a use case for importing Python code by reference to its full file path, inspecting each class found within the source, and performing a task if a particular attribute was found. This was for a command-line interface (CLI) and I wanted the script to be run like the following:
$ python inspect_source.py /full/path/to/source.py
My initial scan of stackoverflow answers didn't provide a solution for exactly what I wanted to do in this case. So I turned to my other favorite resource, Python 3 Module of the Week, and read up on the standard library's importlib and inspect modules. I was able to piece this together.
import importlib
import inspect
import sys
from pathlib import Path
source_path = sys.argv[1]
cwd = Path(__file__).parent
path = Path(source_path)
module_name = path.stem
# Append the parent of the source_path to the python path
sys.path.append(str(path.parent))
print(f"Importing {source_path} as {module_name}")
# Import the source code as a module.
imported_source = importlib.import_module(module_name)
# Use inspect to get all classes.
for name, _class in inspect.getmembers(imported_source, inspect.isclass):
# Check for existence of the target attribute.
try:
attrib = getattr(_class, "my_target_attribute")
except AttributeError:
continue
if attrib is None:
continue
else:
# If the attribute is found, do something.
print(f"{name} -- do something with the target attribute.")
This solution requires that all modules imported by the source file already exist in your environment. Otherwise you will get import errors.