Найти - Пользователи
Полная версия: Динамическая подгрузка
Начало » Python для новичков » Динамическая подгрузка
1
Iskatel
Есть программа, которая обрабатывает события, события различаются, поэтому для каждого свой обработчик.

Эти обработчики я хочу сделать плагинами, чтоб оперативно добавлять/изменять

сделал вот так:

def create_worker(work):
    exec ('import %s' % (work,))
    exec ('worker = %s.%s_wrk()' % (work,work))
    return worker
worker = create_worker(work)
worker.go(data)

Cоответственно в файле с именем, скажем, qwerty.py есть класс qwerty_wrk с методом go

(здесь я не привожу проверку на наличие самого файла, она в другом месте)
впринципе можно из без файла, все в строку пихать, но пока так

Вопросов три:
1. какие подводные камни могут быть при таком подходе?
2. обработчики я хочу заливать с сервера, повторный вызов import импортирует заново или будет использовать кеш? (если нет то как заставить?) или всеж лучше без файла и без import, но строкой
3. есть ли другие варианты “прикрутить плагины”

ЗЫ на import я хочу возложить проблему перезагрузки измененного модуля, ибо если заливать в exec содержимое модуля как строку, боюсь могут появиться забавные эффекты, оставшиеся от старого варианта… Ибо тогда это будет не модуль а часть основной программы, или я ошибаюсь?
Shaman
Почитайте в документации об __import__ и reload.
doza_and
Iskatel
какие подводные камни могут быть при таком подходе?
Импорт это выполнение кода при условии если он не выполнялся раньше. При этом код должен быть в файле.
exec безусловное выполнение без этих ограничений.
Обработчик это функция или функциональный объект который надо обновить безусловно. Не вижу плюсов от импорта по сравнению просто с exeсfile или exec. Вижу только минусы в виде бесполезной борьбы с системой контроля изменений.
Shaman
Модуль может быть и бинарным.
Iskatel
Я вообще не понимаю в чем эта модульность.

Пока что понял, что модуль это свой namespace, пока из него не импортируешь “*”

А вот дальше непонятно. Толи в результате импортов получается какаято общая портянка, как после сишного препроцессора, а затем выполняется. Толи есть механизм контроля этих модулей, и можно рулить ими рантайм.

doza_and
Импорт это выполнение кода при условии если он не выполнялся раньше. При этом код должен быть в файле.
exec безусловное выполнение без этих ограничений.

Что именно там выполняется? обьявление классов/функций, или уже прекомпиляция во чтото рабочее? Сами то функции при импорте не вызываются.

Про “забавные эффекты”: к примеру в первой версии плагина я обьявляю переменную “а” и както инициализирую, а во второй версии забываю про нее… exec, выполнив новый код, по сути перетрет все старые значения, а вот эта переменная будет “гулять” багом. Прога будет работать, ибо в памяти поременная есть… Я надеялся что всетаки есть механизм выгрузки “всего старого модуля” и загрузки нового, тоесть “old ‘a’ not is new ‘a’ ”

ЗЫ. я новичек, и тему в соответствующем раздела создал. Мне б поподробней, желательно со ссылками где почитать по теме.

ЗЫЫ. И самое главное забыл спросить: exec, вызванный в контексте функции, вернет этот worker в области видимости функции, или он будет глобальным?
JOHN_16
Iskatel
Ознакомьтесь с книгой Лутца “Изучаем Python”, там есть главы 18 и 19 - как раз именно то что вам надо - понимание архитектуры программ на питоне, модули и как они работают.
И да, про exec для таких целей забудьте. Это не безопасно. И не практично.

У меня есть проект в котором я делал систему плагинов. В основной части кода я использовал модуль importlib и функцию import_module для импорта модуля, имя которого считывал из конфиг файла. Сами плагины представляли собой python модули расположенной в субдиректории с единым интерфейсом (классом с обязательными методами).
Shaman
Iskatel
Пока что понял, что модуль это свой namespace, пока из него не импортируешь “*”
- нет.
Iskatel
Толи в результате импортов получается какаято общая портянка, как после сишного препроцессора, а затем выполняется. Толи есть механизм контроля этих модулей, и можно рулить ими рантайм.
- второе.
Iskatel
Что именно там выполняется? обьявление классов/функций, или уже прекомпиляция во чтото рабочее? Сами то функции при импорте не вызываются.
Всё выполняемое по правилам языка по ходу текста.
Iskatel
Я надеялся что всетаки есть механизм выгрузки “всего старого модуля” и загрузки нового, тоесть “old ‘a’ not is new ‘a’ ”
Объекты решат почти все ваши проблемы.
Iskatel
Мне б поподробней, желательно со ссылками где почитать по теме.
https://docs.python.org/3.4/tutorial/modules.html
Shaman
Iskatel
И самое главное забыл спросить: exec, вызванный в контексте функции, вернет этот worker в области видимости функции, или он будет глобальным?
Лучше один раз попробовать:
>>> def t():
	exec('import math')
	print math.pi
>>> math
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    math
NameError: name 'math' is not defined
>>> t()
3.14159265359
>>> math.pi
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    math.pi
NameError: name 'math' is not defined
>>> def t():
	exec('import math', globals(), locals())
	print math.pi
>>> t()
3.14159265359
>>> math
Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    math
NameError: name 'math' is not defined
>>> def t():
	exec('import math', globals(), globals())
	print math.pi
>>> t()
3.14159265359
>>> math
<module 'math' (built-in)>
>>> math.pi
3.141592653589793
>>> 
Iskatel
Спасибо, знать бы что пробовать, тут же ни машинных кодов ни регистров процессора не глянешь. Живет какойто своей жизнью…
Shaman
Вот и забудьте пока о них, раз толку никакого.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB