it-swarm.com.ru

Как получить возвращаемое значение при использовании Python exec для объекта кода функции?

В целях тестирования я хочу напрямую выполнить функцию, определенную внутри другой функции.

Я могу получить к объекту кода дочерней функции через код (func_code) родительской функции, но когда я выполняю его, я не получаю возвращаемого значения.

Есть ли способ получить возвращаемое значение из исполняемого кода?

15
user2433423

Да, вам нужно иметь назначение в операторе exec:

>>> def foo():
...     return 5
...
>>> exec("a = foo()")
>>> a
5

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

12
wnnmaw

Нечто подобное может работать:

def outer():
    def inner(i):
        return i + 10


for f in outer.func_code.co_consts:
    if getattr(f, 'co_name', None) == 'inner':

        inner = type(outer)(f, globals())

        # can also use `types` module for readability:
        # inner = types.FunctionType(f, globals())

        print inner(42) # 52

Идея состоит в том, чтобы извлечь объект кода из внутренней функции и создать новую функцию на его основе.

Если внутренняя функция может содержать свободные переменные, требуется дополнительная работа. Вам также придется извлечь их и передать конструктору функции в последнем аргументе (closure).

1
georg

Хотя это самый отвратительный зверь, когда-либо виденный человечеством, это то, как вы можете сделать это, используя глобальную переменную внутри вашего вызова exec:

def my_exec(code):
    exec('global i; i = %s' % code)
    global i
    return i

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

>>> my_exec('1 + 2')
3

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

0
devsnd