Уведомления

Группа в Telegram: @pythonsu

#1 Июль 29, 2015 17:08:31

Iskatel
Зарегистрирован: 2015-07-29
Сообщения: 291
Репутация: +  3  -
Профиль   Отправить e-mail  

Динамическая подгрузка

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

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

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

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 содержимое модуля как строку, боюсь могут появиться забавные эффекты, оставшиеся от старого варианта… Ибо тогда это будет не модуль а часть основной программы, или я ошибаюсь?

Отредактировано Iskatel (Июль 29, 2015 17:14:07)

Офлайн

#2 Июль 29, 2015 20:43:04

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Динамическая подгрузка

Почитайте в документации об __import__ и reload.

Офлайн

#3 Июль 29, 2015 22:34:30

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Динамическая подгрузка

Iskatel
какие подводные камни могут быть при таком подходе?
Импорт это выполнение кода при условии если он не выполнялся раньше. При этом код должен быть в файле.
exec безусловное выполнение без этих ограничений.
Обработчик это функция или функциональный объект который надо обновить безусловно. Не вижу плюсов от импорта по сравнению просто с exeсfile или exec. Вижу только минусы в виде бесполезной борьбы с системой контроля изменений.



Отредактировано doza_and (Июль 29, 2015 22:38:46)

Офлайн

#4 Июль 29, 2015 22:42:24

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Динамическая подгрузка

Модуль может быть и бинарным.

Офлайн

#5 Июль 29, 2015 23:15:06

Iskatel
Зарегистрирован: 2015-07-29
Сообщения: 291
Репутация: +  3  -
Профиль   Отправить e-mail  

Динамическая подгрузка

Я вообще не понимаю в чем эта модульность.

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

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

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

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

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

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

ЗЫЫ. И самое главное забыл спросить: exec, вызванный в контексте функции, вернет этот worker в области видимости функции, или он будет глобальным?

Отредактировано Iskatel (Июль 29, 2015 23:40:58)

Офлайн

#6 Июль 29, 2015 23:42:51

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Динамическая подгрузка

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

У меня есть проект в котором я делал систему плагинов. В основной части кода я использовал модуль importlib и функцию import_module для импорта модуля, имя которого считывал из конфиг файла. Сами плагины представляли собой python модули расположенной в субдиректории с единым интерфейсом (классом с обязательными методами).



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#7 Июль 29, 2015 23:48:02

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Динамическая подгрузка

Iskatel
Пока что понял, что модуль это свой namespace, пока из него не импортируешь “*”
- нет.
Iskatel
Толи в результате импортов получается какаято общая портянка, как после сишного препроцессора, а затем выполняется. Толи есть механизм контроля этих модулей, и можно рулить ими рантайм.
- второе.
Iskatel
Что именно там выполняется? обьявление классов/функций, или уже прекомпиляция во чтото рабочее? Сами то функции при импорте не вызываются.
Всё выполняемое по правилам языка по ходу текста.
Iskatel
Я надеялся что всетаки есть механизм выгрузки “всего старого модуля” и загрузки нового, тоесть “old ‘a’ not is new ‘a’ ”
Объекты решат почти все ваши проблемы.
Iskatel
Мне б поподробней, желательно со ссылками где почитать по теме.
https://docs.python.org/3.4/tutorial/modules.html

Отредактировано Shaman (Июль 30, 2015 00:05:35)

Офлайн

#8 Июль 30, 2015 00:04:37

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Динамическая подгрузка

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
>>> 

Офлайн

#9 Июль 30, 2015 00:17:04

Iskatel
Зарегистрирован: 2015-07-29
Сообщения: 291
Репутация: +  3  -
Профиль   Отправить e-mail  

Динамическая подгрузка

Спасибо, знать бы что пробовать, тут же ни машинных кодов ни регистров процессора не глянешь. Живет какойто своей жизнью…

Отредактировано Iskatel (Июль 30, 2015 00:17:32)

Офлайн

#10 Июль 30, 2015 00:26:59

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Динамическая подгрузка

Вот и забудьте пока о них, раз толку никакого.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version