Сегодня я расскажу, как построить плагиновую архитектуру в python на include'ах.
Наше приложение будет получать команды и раздавать их плагинам в надежде, что какой-нибудь плагин ее да и обработает
Здесь содержится только код «внешней» части примера, и комментировать его, надеюсь, не нужно.
Весь код, относящийся к плагинам мы вынемем в plugin.py
Сейчас уже можно запустить пример:
Сделаем плагин, который будет транслировать команды шеллу и возвращать вывод:
Вот и все!
Скачать исходный код
Наше приложение будет получать команды и раздавать их плагинам в надежде, что какой-нибудь плагин ее да и обработает
Хитрый план
- При запуске сканируем папку с плагинами
- Импортируем все найденные файлы
- При получении команды отсылаем ее каждому плагину
main.py
Здесь содержится только код «внешней» части примера, и комментировать его, надеюсь, не нужно.
Copy Source | Copy HTML
- import plugin
-
- plugin.LoadPlugins()
-
- s = ''
-
- while (s != 'exit'):
- print '>',
- s = raw_input()
- a = s.split(' ')
-
- for p in plugin.Plugins:
- p.OnCommand(a[0], a[1:])
-
Весь код, относящийся к плагинам мы вынемем в plugin.py
plugin.py
Copy Source | Copy HTML
- import os
- import sys
-
- # Экземпляры загруженных плагинов
- Plugins = []
-
- # Базовый класс плагина
- class Plugin(object):
- Name = 'undefined'
-
- # Методы обратной связи
- def OnLoad(self):
- pass
-
- def OnCommand(self, cmd, args):
- pass
-
-
- def LoadPlugins():
- ss = os.listdir('plugins') # Получаем список плагинов в /plugins
- sys.path.insert( 0, 'plugins') # Добавляем папку плагинов в $PATH, чтобы __import__ мог их загрузить
-
- for s in ss:
- print 'Found plugin', s
- __import__(os.path.splitext(s)[ 0], None, None, ['']) # Импортируем исходник плагина
-
- for plugin in Plugin.__subclasses__(): # так как Plugin произведен от object, мы используем __subclasses__, чтобы найти все плагины, произведенные от этого класса
- p = plugin() # Создаем экземпляр
- Plugins.append(p)
- p.OnLoad() # Вызываем событие загруки этого плагина
-
- return
-
-
plugins/foo.py — пример плагина
Copy Source | Copy HTML
- from plugin import Plugin
-
- class HelloPlugin(Plugin): # производим наш плагин от родительского класса
- Name = 'HelloPlugin v 1.0 Extreme Edition'
-
- # замещаем нужные методы
- def OnLoad(self):
- print 'HelloPlugin 1.0 Extreme VIP Edition Loaded!'
-
- def OnCommand(self, cmd, args):
- if (cmd == 'hello' and len(args)> 0):
- print 'It\'s', args[ 0], '!\nJeez, man, nice to meet you!'
- return True
- else:
- return False
-
-
Сейчас уже можно запустить пример:
$ python main.py
Found plugin foo.py
HelloPlugin 1.0 Extreme VIP Edition Loaded!
> hello %username%
It's %username%!
Jeez, man, nice to meet you!
>
plugins/shell.py — плагин посложнее
Сделаем плагин, который будет транслировать команды шеллу и возвращать вывод:
Copy Source | Copy HTML
- from plugin import Plugin
- import commands
-
- class ShellPlugin(Plugin):
- Name = 'Shell plugin'
-
- def OnLoad(self):
- print 'Shell plugin loaded.'
-
- def OnCommand(self, cmd, args):
- if (cmd == 'run'):
- print commands.getoutput (" ".join(args))
- return True
- else:
- return False
-
$ python main.py
Found plugin shell.py
Found plugin foo.py
Shell plugin loaded.
HelloPlugin 1.0 Extreme VIP Edition Loaded!
> run uname -r
2.6.31-14-generic
> exit
Вот и все!
Скачать исходный код