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

<p>в целях тестирования я хочу напрямую выполнить функцию, определенную внутри другой функции.</p><p>я могу получить к объекту кода дочерней функции через код (func\_code) родительской функции, но когда я выполняю его, я не получаю возвращаемого значения.</p><p>есть ли способ получить возвращаемое значение из исполняемого кода?</p>

<p>да, вам нужно иметь назначение в операторе <code>exec</code>:</p><pre><code>>>> def foo(): ... return 5 ... >>> exec("a = foo()") >>> a 5 </code></pre><p>это, вероятно, не относится к вашему случаю, поскольку оно используется в контролируемом тестировании, но<em> будьте осторожны с использованием <code>exec</code> с пользовательским вводом. </em> </p>

<p>нечто подобное может работать:</p><pre><code>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 </code></pre><p>идея состоит в том, чтобы извлечь объект кода из внутренней функции и создать новую функцию на его основе.</p><p>если внутренняя функция может содержать свободные переменные, требуется дополнительная работа. вам также придется извлечь их и передать конструктору функции в последнем аргументе (<code>closure</code>).</p>

<p>хотя это самый отвратительный зверь, когда-либо виденный человечеством, это то, как вы можете сделать это, используя глобальную переменную внутри вашего вызова exec:</p><pre><code>def my\_exec(code): exec('global i; i = %s' % code) global i return i </code></pre><p>это неправильное использование глобальных переменных для передачи ваших данных через границу.</p><pre><code>>>> my\_exec('1 + 2') 3 </code></pre><p>само собой разумеется, что вы должны<em> никогда </em>разрешать любые пользовательские вводы для ввода этой функции, так как это представляет чрезвычайную угрозу безопасности.</p>