Loading a class of unknown name in a dynamic location

Currently I am extracting files to the temp directory of the operating system. One of the files is a Python file containing a class which I need to get a handle of. The Python's file is known, but the name of the class inside the file is unknown. But it is safe to assume, that the there is only one single class, and that the class is a subclass of another.

I tried to work with importlib, but I am not able to get a handle of the class.

So far I tried:

# Assume 
# module_name contains the name of the class and     -> "MyClass"
# path_module contains the path to the python file   -> "../Module.py"
spec = spec_from_file_location(module_name, path_module)
module = module_from_spec(spec)
for pair in inspect.getmembers(module):
    print(f"{pair[1]} is class: {inspect.isclass(pair[1])}")

When I iterate over the members of the module, none of them get printed as a class.

My class in this case is called BasicModel and the Output on the console looks like this:

BasicModel is class: False

What is the correct approach to this?

Edit:

As the content of the file was requested, here you go:

class BasicModel(Sequential):

    def __init__(self, class_count: int, input_shape: tuple):
        Sequential.__init__(self)
        self.add(Input(shape=input_shape))
        self.add(Flatten())
        self.add(Dense(128, activation=nn.relu))
        self.add(Dense(128, activation=nn.relu))
        self.add(Dense(class_count, activation=nn.softmax))

Upvotes: 1

Views: 825

Answers (1)

Durtal
Durtal

Reputation: 1028

Use dir() to get the attributes of the file and inspect to check if the attribute is a class. If so, you can create an object.

Assuming that your file's path is /tmp/mysterious you can do this:

import importlib
import inspect
from pathlib import Path
import sys

path_pyfile = Path('/tmp/mysterious.py')
sys.path.append(str(path_pyfile.parent))
mysterious = importlib.import_module(path_pyfile.stem)

for name_local in dir(mysterious):
    if inspect.isclass(getattr(mysterious, name_local)):
        print(f'{name_local} is a class')
        MysteriousClass = getattr(mysterious, name_local)
        mysterious_object = MysteriousClass()

Upvotes: 4

Related Questions