Вопрос

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

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

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

Это было полезно?

Решение

используя режиссер () и модуль imp

Другие советы

Я думаю, что лучший способ сделать такого рода плагины - это использовать entry_points и тот API для их запроса.

Когда я был в некотором роде и только начинал программировать на 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]

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

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

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

Запомни:"явное лучше неявного" - это часть дзена python.

Вы можете попробовать 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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top