Разобрать файл Python и оценить выбранные функции - PullRequest
2 голосов
/ 10 января 2011

У меня есть файл, который содержит несколько функций Python, каждая с некоторыми операторами.

def func1():
    codeX...
def func2():
    codeY...

codeX и codeY могут быть несколькими операторами.Я хочу иметь возможность проанализировать файл, найти функцию по имени, а затем оценить код в этой функции.

С помощью модуля ast я могу проанализировать файл, найти объекты FunctionDef и получить списокобъектов Stmt, но как мне превратить это в байт-код, который я могу передать eval?Должен ли я использовать модуль компиляции или модуль парсера вместо этого?

По сути, функции def используются только для создания отдельных блоков кода.Я хочу иметь возможность захватить любой блок кода с указанным именем и затем выполнить этот код в eval (предоставляя свои собственные объекты локальной / глобальной области видимости).Если есть лучший способ сделать это, чем то, что я описал, это тоже будет полезно.

Спасибо

Ответы [ 3 ]

2 голосов
/ 10 января 2011

Я хочу иметь возможность получить любой блок кода с указанным именем и затем выполнить этот код ... (предоставив мои собственные объекты локальной / глобальной области видимости).

Наивное решение выглядит следующим образом.Это основано на предположении, что не все функции зависят от глобальных переменных.

from  file_that_contains_several_python_functions import *
Direction = some_value
func1()
func2()
func3()

Что должно делать именно то, что вы хотите.

Однако, если все ваши функции полагаются на глобальные переменные - проект, который напоминает FORTRAN эпохи 1970-х годов - тогда вам нужно сделать что-то немного более сложное.И вы должны переписать все свои глобальные функции, как это.

 def func1( context )
     globals().update( context )
     # Now you have access to all kinds of global variables

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

1 голос
/ 10 января 2011

Использование Python 2.6.4:

text = """
def fun1():
    print 'fun1'

def fun2():
    print 'fun2'

"""

import ast
tree = ast.parse(text)
# tree.body[0] contains FunctionDef for fun1, tree.body[1] for fun2

wrapped = ast.Interactive(body=[a.body[1]])
code = compile(wrapped, 'yourfile', 'single')
eval(code)
fun2() # prints 'fun2'

Посмотрите на грамматику в ast doc: http://docs.python.org/library/ast.html#abstract-grammar. Оператор верхнего уровня должен быть либо модулем, либо интерактивным, либо выражением, поэтому вам нужно заключить функцию def в одну из них.

1 голос
/ 10 января 2011

Если вы используете Python 2.6 или новее, функция compile() принимает объекты AST в дополнение к исходному коду.

>>> import ast
>>> a = ast.parse("print('hello world')")
>>> x = compile(a, "(none)", "exec")
>>> eval(x)
hello world

Все эти модули переставлены для Python 3.

...