2016-12-21 5 views
1

У меня есть сгенерированный сгенерированный фрагмент кода Python, который я хотел бы exec() из экземпляра класса.Вызов функций в exec() из экземпляра класса

Упрощенный фрагмент кода выглядит следующим образом:

prog = """ 
def func1(): 
    func2() 

def func2(): 
    pass 

func1() 
""" 

class test(): 
    def run(self): 
     exec(prog) 

test().run() # results in NameError: name 'func2' is not defined 
exec(prog)  # works 

Хотя func1() можно назвать в обоих случаях, func2 не найден, когда exec() «ИНГ из класса. Если я сначала запустил exec(prog), то даже test().run() преуспеет. Кажется, что предыдущий вызов exec оставил func2 в некотором месте в пространстве имен, где он может быть позже найден при вызове из класса.

Есть ли простой и чистый способ вызвать такой фрагмент кода, содержащий несколько функций из класса?

+0

Интересно. Ваш код работает как написанный на Python 2, но я получаю вашу ошибку на Python 3. Можете ли вы подтвердить, что находитесь на Python 3? –

+0

Ах да. Прочитайте это: http://stackoverflow.com/a/15087355/5014455 –

+0

Да, я использую Python3. –

ответ

2

Вы можете использовать exec(prog, globals()) для выполнения кода в глобальном пространстве имен.

+0

Большое спасибо. Это делает именно то, на что я надеялся. –

+0

Вы не знаете, почему func1() может быть вызван в моем первоначальном подходе и почему только func2 отсутствует? Почему это ограничение ограничено только func2? –

+0

func1 и func2 существуют в пространстве имен (то есть в словаре), где выполняется выполнение. В вашем коде это локальное пространство имен функции 'run()'. Поскольку 'func1()' вызывается в том же пространстве имен, он работает. – Gribouillis

1

Не то, что я поддерживаю, используя exec ... Но объявить имя функции global:

prog = """ 
global func1, func2 
def func1(): 
    func2() 

def func2(): 
    pass 

func1() 
""" 
+0

Выглядит хорошо. Но мне придется разбирать входящий код, искать функции и автоматически добавлять глобальный оператор. Подход exec (prog, globals()) запускает немодифицированный код. –

1

Это избыточно использовать Exec для этого.

класс сам по себе является исполняемым заявлением.

+0

Но класс не анализирует и не выполняет текстовые строки. Итак, 'exec' по-прежнему необходим. – DyZ

+0

Да. Это просто упрощенная проверка. На самом деле код, который нужно выполнить, происходит откуда-то еще. –

Смежные вопросы