denz
Март 30, 2007 18:17:15
Всем привет. Заранее благодарен за любые идеи.
Нужно повыполнять кучу кусков кода, который хранится в разных файлах.
В данный момент используется конструкция, написанная в соответствии с мануалом:
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
Март 30, 2007 19:25:05
А что конкретно не оптимально?
denz
Март 30, 2007 19:56:19
Неоптимально затягивать все глобалсы внутрь отдельно стоящего кода, вместо того, чтобы втянуть кусок кода в существующий объект, в котором уже есть все окружение.
Эти куски - они довольно маленькие, и их может быть очень много.
xonix
Март 30, 2007 20:11:28
И что тут неоптимального, передаваться-то будут только ссылки на глобалзы, ничего копироваться при этом не будет, ведь…
Да и вообще можно попробовать другие пути выполнения таких файликов, начиная от примерно такого
от
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
Март 30, 2007 20:17:02
preprocessor_src - компільований кусок, який не приймає ніяких параметрів, тому і фунція нічо не приймає. Щоб вона шось приймала треба той compile замінити на CodeObject, що буде приймати параметри. Але ліпше мені здається той self передати в глобалс.
tabajara
Март 30, 2007 20:21:52
denz
Неоптимально затягивать все глобалсы внутрь отдельно стоящего кода
“затягивать все глобалсы внутрь отдельно стоящего кода” == “затягнути 1 вказівник розміром 4 байти”
denz
Апрель 1, 2007 13:35:47
to xonix:
К сожалению выполнять непосредственно из файлов я не могу - куски эти предварительно обрабатываются и в перспективе будут шаблонизироваться, а через временные файлы на диске я ходить не могу, т.к есть “угроза” использования флеш дисков.
to tabajara:
Кто такой CodeObject? Не вижу такого в мануале. Есть только мутно документированный new.code().
В общем я пошел путем затягивания __builtins__ и self в compile(). Тащить туды все globals() не хочу, т.к. в перспективе встанет вопрос под названием security а куски кода будут писаться не мной. Текущий вариант правда тоже нифига не секьюрный….
P.S. Я почему именно так вопрос поставил - потому что, по сути, питон все время создает методы и создает их параметры, вот и стало интересно как это сделать руцями.
Всем спасибо за содействие.