Chetchaiyan
Chetchaiyan

Reputation: 271

Get A list of class in python files

I try to get the list of class from python file using python. After a few search, I get the code which I think it's work as follow

def get_class_from_file(class_obj, file, path='app', exclude=[]):
    class_list = []
    module = importlib.import_module(path + '.' + file)
    for x in dir(module) :
        app_cls = getattr( importlib.import_module(path + '.' + file), x )
        try :
            if app_cls and issubclass(app_cls, class_obj) and app_cls != class_obj and app_cls not in exclude:
                class_list.append( (file, x) )
        except TypeError :
            pass
    return class_list

However, I found out that the code don't get only the list of the class, but It still keep showing me the superclass of the class inside the file, here is example

file_1.py

class A:
    pass

class B(A):
    pass

file_2.py

class C(B):
    pass

class D:
    pass

when I call the function as class_list = get_class_from_file(A, 'file_2')

I expect the result would be [C], but It return [C, B] as B is one of super class of C

Please help me fix this, I just want class inside the given file, not any superclass of them. By the way, I use exclude for fixing it at first, but It isn't give me a long run solution.

Upvotes: 1

Views: 164

Answers (1)

RemcoGerlich
RemcoGerlich

Reputation: 31260

The problem is that imported modules are also found. You can check a class' __module__ attribute to see if it originates from the current module or was imported into it.

You also have importlib.import_module(path + '.' + file) twice, I removed one of them. I renamed x to name.

def get_class_from_file(class_obj, file, path='app', exclude=[]):
    class_list = []
    module_path = path + '.' + file
    module = importlib.import_module(module_path)
    for name in dir(module) :
        app_cls = getattr(module, name)
        try:
            if (issubclass(app_cls, class_obj) and
                 app_cls != class_obj and
                 app_cls not in exclude and
                 app_cls.__module__ == module_path):
            class_list.append( (file, name) )
        except TypeError:
            # Not a class
            pass
    return class_list

Upvotes: 2

Related Questions