Как проверить, использовался ли класс в другом классе в том же модуле? - PullRequest
2 голосов
/ 21 октября 2019

У меня есть модуль, который имеет несколько классов. Один класс, скажем, A, зависит от другого, скажем, B, , т.е. A имеет метод, который создает объект B и использует его. Обратите внимание, что в этом нет никакого наследования, а просто тот факт, что A зависит от B.

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

Приведите минимальный жизнеспособный пример:

class CarPollutionPermit:
    def __init__(self):
        self.permit = False

    def check_permit(self, year, mileage):
        if year < 2016:
            return False
        if mileage > 15:
            return True
        return False


class BikePollutionPermit:
    def __init__(self):
        self.permit = True

    def check_permit(self, year, mileage):
        if year < 2010:
            self.permit = False
            return False
        if mileage < 40:
            if year > 2016:
                return True
            self.permit = False
            return False
        self.permit = True
        return True


class TractorPollutionPermit:
    def fetch_tractor(self, year, is_farmer):
        if year > 2015 and is_farmer:
            return True
        if year > 2017:
            return True
        return False


class TractorPesticides(TractorPollutionPermit):
    def fetch_pesticides_permit(self, pesticide_effect):
        if pesticide_effect < 10:
            if self.fetch_tractor(2019, True):
                return True
            return False
        car_pollution_permit = CarPollutionPermit()
        return (car_pollution_permit.check_permit(2019, 16))

Как видите,класс TractorPesticides зависит от CarPollutionPermit. Я должен извлечь это отношение. База кода написана на Python3, и мой код для выполнения этой функции также написан на python3.

1 Ответ

1 голос
/ 21 октября 2019

Вам нужно работать с abstract syntax tree вашего модуля. Пример, который работает хотя бы с вашим модулем и показывает, что TractorPesticides зависит от CarPollutionPermit:

import ast


with open('test.py') as f:
    data = f.read()
    module = ast.parse(data)
    classes = [
        obj
        for obj in module.body
        if isinstance(obj, ast.ClassDef)
    ]
    class_names = [obj.name for obj in classes]
    dependencies = {name: [] for name in class_names}
    for cls in classes:
        for node in ast.walk(cls):
            if isinstance(node, ast.Call):
                if isinstance(node.func, ast.Name):
                    if node.func.id != cls.name and node.func.id in class_names:
                        dependencies[cls.name].append(node.func.id)
    for class_name, dependency in dependencies.items():
        print(class_name, dependency)

Вывод:

CarPollutionPermit []
BikePollutionPermit []
TractorPollutionPermit []
TractorPesticides ['CarPollutionPermit']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...