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

func=new.function(compile(preprocessor_src,filename,“exec”),{“global1”:some_var1,“global2”:some_var2})
func()

Передаваемые global1 и global2 соответственно используются в кусках кода.
Соответственно никаких других глобалов в этих кусках нет. Работает только голый питонический синтаксис.
Можно импортировать туда все необходимые глобалсы. Но это ж неоптимально, учитывая, что код выполняется внутри объекта.

Меняем пусковую конструкцию на

func=new.function(compile(preprocessor_src,filename,“exec”),{“global1”:some_var1,“global2”:some_var2})
func()
self.preprocessor=new.instancemethod(func,self)
self.preprocessor()

На что (очевидно) получаем от питона версии 2.4 ответ:
TypeError: ?() takes no arguments (1 given)

Итаг вопрос:
Как определить агрументы для self.preprocessor?
xonix
А что конкретно не оптимально?
denz
Неоптимально затягивать все глобалсы внутрь отдельно стоящего кода, вместо того, чтобы втянуть кусок кода в существующий объект, в котором уже есть все окружение.
Эти куски - они довольно маленькие, и их может быть очень много.
xonix
И что тут неоптимального, передаваться-то будут только ссылки на глобалзы, ничего копироваться при этом не будет, ведь…

Да и вообще можно попробовать другие пути выполнения таких файликов, начиная от примерно такого
от
sys.path.append(DIR_WITH_PLUGINS)
for file in os.listdir(DIR_WITH_PLUGINS):
   __import__(file, globals(), locals(), ())
до
for file in os.listdir(DIR_WITH_PLUGINS):
   exec open(os.path.join(DIR_WITH_PLUGINS, file)).read() in globals()
или просто
for file in os.listdir(DIR_WITH_PLUGINS):
   execfile(os.path.join(DIR_WITH_PLUGINS, file)), globals(), locals())

код не тестировал
tabajara
preprocessor_src - компільований кусок, який не приймає ніяких параметрів, тому і фунція нічо не приймає. Щоб вона шось приймала треба той compile замінити на CodeObject, що буде приймати параметри. Але ліпше мені здається той self передати в глобалс.
tabajara
denz
Неоптимально затягивать все глобалсы внутрь отдельно стоящего кода
“затягивать все глобалсы внутрь отдельно стоящего кода” == “затягнути 1 вказівник розміром 4 байти”
denz
to xonix:
К сожалению выполнять непосредственно из файлов я не могу - куски эти предварительно обрабатываются и в перспективе будут шаблонизироваться, а через временные файлы на диске я ходить не могу, т.к есть “угроза” использования флеш дисков.

to tabajara:
Кто такой CodeObject? Не вижу такого в мануале. Есть только мутно документированный new.code().

В общем я пошел путем затягивания __builtins__ и self в compile(). Тащить туды все globals() не хочу, т.к. в перспективе встанет вопрос под названием security а куски кода будут писаться не мной. Текущий вариант правда тоже нифига не секьюрный….

P.S. Я почему именно так вопрос поставил - потому что, по сути, питон все время создает методы и создает их параметры, вот и стало интересно как это сделать руцями.

Всем спасибо за содействие.
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