Второй пример, приближенный к реальности
В этом примере мы заранее не будем знать ни имена модулей плагинов, ни имена классов, содержащихся внутри. А так же потребуем, чтобы все плагины были производными от базового класса baseplugin. В папке plugins кроме файла
__init__.py лежат еще три модуля. Один из них с именем
base.py содержит в себе базовый класс:
PHP код:
#-*- coding: utf-8 -*-
class baseplugin (object):
def run (self):
pass
Во втором модуле my_plugin_1.py содержится один класс:
PHP код:
#-*- coding: utf-8 -*-
import base
class pluginClass1 (base.baseplugin):
def __init__(self):
pass
def run (self):
print " Hello, first plug-in!"
А в третьем my_plugin_2.py два класса:
PHP код:
#-*- coding: utf-8 -*-
import base
class pluginClass2 (base.baseplugin):
def __init__(self):
pass
def run (self):
print " Hello, second plug-in!"
class pluginClass3 (base.baseplugin):
def __init__(self):
pass
def run (self):
print " Hello, third plug-in!"
Ниже располагается код, который получает имена всех файлов в папке
plugins. Затем импортирует найденные модули (кроме файлов
base.py и
__init__.py). После этого перебирает все атрибуты внутри каждого импортированного модуля, создает экземпляры найденных внутри классов, вроизводных от base.baseplugin и выполняет метод run.
PHP код:
#-*- coding: utf-8 -*-
import os
import inspect
plugin_dir = "plugins"
import plugins.base
# Сюда добавляем имена загруженных модулей
modules = []
# Перебирем файлы в папке plugins
for fname in os.listdir(plugin_dir):
# Нас интересуют только файлы с расширением .py
if fname.endswith (".py"):
# Обрежем расширение .py у имени файла
module_name = fname[: -3]
# Пропустим файлы base.py и __init__.py
if module_name != "base" and module_name != "__init__":
print "Load module %s" % module_name
# Загружаем модуль и добавляем его имя в список загруженных модулей
package_obj = __import__(plugin_dir + "." + module_name)
modules.append (module_name)
print "dir(package_obj) = " + str (dir(package_obj) )
print
else:
print "Skip " + fname
# Перебираем загруженные модули
for modulename in modules:
module_obj = getattr (package_obj, modulename)
print modulename
print dir (module_obj)
# Перебираем все, что есть внутри модуля
for elem in dir (module_obj):
obj = getattr (module_obj, elem)
# Это класс?
if inspect.isclass (obj):
# Класс производный от baseplugin?
if issubclass (obj, plugins.base.baseplugin):
# Создаем экземпляр и выполняем функцию run
a = obj()
a.run()
print
Во время выполнения скрипт выводит дополнительную информацию о ходе работы. В результате на экране будут выведены следующие сообщения:
Код:
Skip base.py
Load module my_plugin_1
dir(package_obj) = ['__builtins__', '__doc__', '__file__', '__name__', '__path__', 'base', 'my_plugin_1']
Load module my_plugin_2
dir(package_obj) = ['__builtins__', '__doc__', '__file__', '__name__', '__path__', 'base', 'my_plugin_1', 'my_plugin_2']
Skip __init__.py
my_plugin_1
['__builtins__', '__doc__', '__file__', '__name__', 'base', 'pluginClass1']
Hello, first plug-in!
my_plugin_2
['__builtins__', '__doc__', '__file__', '__name__', 'base', 'pluginClass2', 'pluginClass3']
Hello, second plug-in!
Hello, third plug-in!
Скачать этот пример полностью можно по адресу
http://jenyay.net/uploads/Programming/PyPlugins/test3.zip