Подтвердить что ты не робот

Как найти все дочерние модули в Python?

Хотя в Python довольно сложно вводить "дочерний" модуль в другой модуль и перечислять его атрибуты, становится немного сложнее, если вы хотите импортировать все дочерние модули.

Я создаю библиотеку инструментов для существующего 3D-приложения. Каждый инструмент имеет свой собственный пункт меню и подменю. Я хотел бы, чтобы инструмент отвечал за создание собственного меню, поскольку многие из них меняются в зависимости от контекста и шаблонов. Я хочу, чтобы мой базовый модуль мог найти все дочерние модули и проверить функцию create_menu() и вызвать его, если он найдет его.

Каков самый простой способ обнаружить все дочерние модули?

4b9b3361

Ответ 3

Когда я был добрым и только начинал программировать на Python, я написал это для моего модульного IRC-бота:


    # Load plugins

    _plugins = []

    def ifName(name):
        try:
            return re.match('([^_.].+)\.[^.]+', a).group(1)
        except:
            return None

    def isValidPlugin(obj):
        from common.base import PluginBase
        try:
            if obj.__base__ == PluginBase:
                return True
            else:
                return False
        except:
            return False

    plugin_names = set(ifilter(lambda a: a!=None, [ifName(a) for a in os.listdir(os.path.join(os.getcwd(), 'plugins'))]))
    for plugin_name in plugin_names:
        try:
            plugin = __import__('plugins.'+plugin_name, fromlist=['plugins'])
            valid_plugins = filter(lambda a: isValidPlugin(a), [plugin.__getattribute__(a) for a in dir(plugin)])
            _plugins.extend(valid_plugins)
        except Exception, e:
            logger.exception('Error loading plugin %s', plugin_name)

    # Run plugins

    _plugins = [klass() for klass in _plugins]

Это не безопасный или "правильный" способ, но, возможно, это будет полезно. Это очень старый код, поэтому, пожалуйста, не бить меня.

Ответ 4

Решение выше, перемещая файловую систему для поиска подмодулей, нормально, пока вы реализуете каждый плагин как модуль на основе файловой системы.

Более гибким способом будет явный список плагинов в вашем основном модуле и каждый плагин (будь то модуль, созданный файлом, динамически или даже экземпляр класса), добавляя себя в этот список явно. Может быть, через функцию registerPlugin.

Помните: "Явное лучше, чем неявное" является частью zen python.

Ответ 5

Вы можете попробовать glob bing каталог:

import os
import glob

modules = glob.glob(os.path.join('/some/path/to/modules', '*.py'))

Затем вы можете попробовать импортировать их:

checked_modules
for module in modules:
    try:
        __import__(module, globals(), locals()) # returns module object
    except ImportError:
        pass
    else:
        checked_modules.append(module)