Как найти python иерархию классов между модулями? - PullRequest
2 голосов
/ 10 апреля 2020

Как найти родительский класс и подклассы в разных модулях без выполнения кода (stati c анализ)

Модуль Содержит __init__.py и 4 файла, как показано ниже

Пример first_file.py

class Parent(object):
    def __init__(self):
        pass

    def method1(self):
        print('parent')

Пример second_file.py

from first_file import Parent
class Child(Parent):
    def __init__(self):
        pass

    def method1(self):
        print('child')

Пример third_file.py

from first_file import Parent
class Child1(Parent):
    def __init__(self):
        pass

    def method1(self):
        print('child1')

Пример четвёртый_файл.py

from second_file import Child
class Child2(Child):
    def __init__(self):
        pass

    def method1(self):
        print('child2')

Я хочу способ перечисления подклассов родительского данного имени файла и примера класса

>>> findclasshierchay first_file.py --class Parent

, и он перечислит все подклассы с именами файлов

1 Ответ

0 голосов
/ 11 апреля 2020

Вот пример использования cls.mro().

Отказ от ответственности, я не знаю, считаете ли вы, что это с кодом или нет. Это , а не stati c анализ, но если у вас нет сильных побочных эффектов при загрузке модуля, это тоже не так уж и много.

file1.py

class File1:
    pass

file2.py

from file1 import File1

class File2(File1):
    pass

listhier.py

import sys
import copy
import os
from importlib import import_module
from importlib.util import find_spec as importlib_find


#shamelessly copied from django ?

def import_string(dotted_path):
    """
    Import a dotted module path and return the attribute/class designated by the
    last name in the path. Raise ImportError if the import failed.
    """
    try:
        module_path, class_name = dotted_path.rsplit('.', 1)
    except ValueError as err:
        raise ImportError("%s doesn't look like a module path" % dotted_path) from err

    module = import_module(module_path)

    try:
        return getattr(module, class_name)
    except AttributeError as err:
        raise ImportError('Module "%s" does not define a "%s" attribute/class' % (
            module_path, class_name)
        ) from err


toload = sys.argv[1]

cls = import_string(toload)

for cls_ in cls.mro():
    print("%s.%s" % (cls_.__module__, cls_.__name__))

python listhier.py file2.File2

вывод:

file2.File2
file1.File1
builtins.object
...