2

I have a single folder ('root') which contains various subfolders and *.py files. 'root' is not a package just a folder with different scripts. I'm trying to find all scripts in 'root' that contain classes that inherit from a specific baseclass. The goal is to present the user with a specific selection of scripts to choose from.

The most obvious way to find subclasses is to use __subclasses__() which however requires all classes to be loaded (i.e. calling __subclasses__() on a class will only find those subclasses that are currently loaded), which isn't all that great when you have a folder full of individual scripts.

I tried to search for all *.py files in 'root' and than tried to import them one by one using importlib, which is not only painfully slow (as you might imagine), I didn't even get it to work properly.

The baseclass is defined as MyBaseClass(with_metaclass(abc.ABCMeta, SomeOtherClass)) I know very little about abc so I'm not sure if it provides any functionality that could help. (I'm looking into this right now)

Java has a neat Lookup package (http://bits.netbeans.org/7.4/javadoc/org-openide-util-lookup/org/openide/util/Lookup.html) which allows you to tag classes and later lookup all classes with a certain tag. (It usually does its lookup within the confines of a jar, so not exactly the same thing)

My question is: Is there any decent way to get this to work?

EDIT

originally posted as a comment, put here for better visibility:

"Those scripts are different launch scripts & producers for a simulation. They all inherit from 1 of only a few baseclasses. The baseclass can be changed if needed. So I was looking for a way to gather all scripts that inherit from a specific baseclass to present a choice of specific scripts."

The code I currently use to crawl a directory and import all *.py files:

def all_files(directory):
    for path, dirs, files in os.walk(directory):
        for f in files:
            if f.endswith('.py'):
                yield os.path.join(path, f)
# Found here: 
# https://stackoverflow.com/questions/3137731/is-this-correct-way-to-import-python-scripts-residing-in-arbitrary-folders
def import_from_absolute_path(fullpath, global_name=None):
    script_dir, filename = os.path.split(fullpath)
    script, ext = os.path.splitext(filename)

    sys.path.insert(0, script_dir)
    try:
        module = __import__(script)
        if global_name is None:
            global_name = script
        globals()[global_name] = module
        sys.modules[global_name] = module
    except ModuleNotFoundError as mnf:
        print(mnf)
    except ImportError as ie:
        print(ie)
    except FileNotFoundError as fnf:
        print(fnf)
    finally:
        del sys.path[0]
orangeInk
  • 1,360
  • 8
  • 16
  • Why isn't it a package? What do you need this for? – jonrsharpe May 31 '17 at 14:14
  • 2
    Please [edit] the question to give more context, otherwise we could solve an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – jonrsharpe May 31 '17 at 14:26
  • 1
    You're going to have to import (load) each one...and it's not clear why that would be "painfully" slow. It's quite possible that this could be sped up if you showed us your code. Regardless, the more important question is "Why?"—what are you trying to accomplish by doing this and what do you consider a "decent" way? – martineau May 31 '17 at 14:40
  • 1. Code: see edit 2.Why?: because those scripts are partially differentiated by the base class they use (which can change, the base class I mean) so I was looking for a way to dynamically group them so that users will only be able to choose a script that implements a specific base class 3. Decent way?: What I meant was: "Is there a 'default' way of dealing with this that I'm not aware of? If not, do you have any suggestions on how I might go about doing this?" – orangeInk Jun 01 '17 at 07:47

0 Answers0