Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Import class dynamically
#1
I have two base classes FirstBaseClass and SecondBaseClass and lot of theirs subclasses. Each subclass defined in the separate file, location of these files is known. I need to import and instantiate subclasses programmatically. Now I use following approach:

import inspect
import importlib

class_name = "FirstChildClass"
file_path = "/path/to/class.py"

try:
    spec = importlib.util.spec_from_file_location(class_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    for x in dir(module):
        obj = getattr(module, x)
        if inspect.isclass(obj) and (issubclass(obj, FirstBaseClass) or issubclass(obj, SecondBaseClass)) and obj.__name__ == class_name:
            return obj()
except ImportError as e:
    print(e)    
But problem is that I need to know class name. Is it possible to import class from file without knowing its name, assuming that only one class defined in that file?
Reply
#2
(Jan-30-2018, 06:42 AM)voltron Wrote: But problem is that I need to know class name.
If there is only one class, only one object will match inspect.isclass(obj) so you don't need to know the class name. Is it your code?
Reply
#3
(Jan-30-2018, 07:04 AM)Gribouillis Wrote: If there is only one class, only one object will match inspect.isclass(obj) so you don't need to know the class name. Is it your code?
Maybe I'm doing something wrong, but this does not work. In class code I have something like this
import os
from program.package.FirstBaseClass import FirstBaseClass
from program.package.SomeClass import SomeClass
...
(more imports here)

class FirstChildClass(FirstBaseClass):
    ...
    (implementation here)
When I run import code without class name check, e.g. just inspect.isclass(obj) it returns FirstBaseClass, then SomeClass... Class defined in the code returned in the end.
Reply
#4
You can use eg inspect.getmodule(obj), or inspect.getsourcefile(obj) to differentiate between classes defined here and imported classes.
Reply
#5
Using inspect.getmodule(obj) and inspect.getsourcefile(obj) does not worked for me, but I managed to solve this by checking class name like this

if inspect.isclass(obj) and issubclass(obj, (FirstBaseClass, SecondBaseClass)) and obj.__name__ not in ("FirstBaseClass", "SecondBaseClass"):
    # do something
Thanks a lot for your help!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Dynamically setting nested class be_ams 0 1,526 Apr-06-2022, 02:09 PM
Last Post: be_ams
  dynamically define class's michavardy 1 2,095 Feb-26-2019, 04:20 PM
Last Post: buran
  Help creating a class instance dynamically Kotevski 9 5,388 Aug-17-2018, 05:23 AM
Last Post: Gribouillis
  import just one class from a file sylas 4 3,300 Apr-25-2018, 08:56 PM
Last Post: sylas

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020