Следующее работает и выводит 42, как и ожидалось:
import textwrap
def test_compile():
code_str = """
def bump(x):
return x + 1
print(); print(bump(41))
"""
dedented_code_str = textwrap.dedent(code_str)
code_obj = compile(dedented_code_str, filename='<string>', mode='exec')
exec(code_obj)
Итак, dump
определяется при компиляции print
и exe c 'd. Однако вставка лямбда-выражения вызывает исключение из exec
, а именно то, что bump
не найден (удаление некоторых строк для краткости):
exec(code_obj)
test_compile.py:48:
<string>:5: in <module>
E NameError: name 'bump' is not defined
Вот оскорбление попытка скомпилировать:
import textwrap
def test_compile_with_lambda():
code_str = """
def bump(x):
return x + 1
debug_me = (lambda y: bump(y))(41)
print(); print(debug_me)
"""
dedented_code_str = textwrap.dedent(code_str)
code_obj = compile(dedented_code_str, filename='<string>', mode='exec')
exec(code_obj)
Код предметной области, а именно
def bump(x):
return x + 1
debug_me = (lambda y: bump(y))(41)
print(); print(debug_me)
работает во всех других средах или контекстах, которые я пробовал: на верхнем уровне, как сценарий; внутри обычной вызывающей функции (при этом bump
определен либо внутри, либо снаружи обычной вызывающей функции); и под pytest. Я не воспроизводил здесь эти случаи, чтобы сэкономить место, но все, что интуитивно ожидалось, работает, похоже, работает. Я ожидал, что лямбда-выражение должно видеть bump
, но компилятор с этим не согласен.
Между прочим, если этот предметный код либо вызывается, либо компилируется и (что особенно важно) exe c 'd извне, но в том же файле с test_compile_with_lambda
, тогда bump
определяется в лямбда-выражении и test_compile_with_lambda
работает. Предположительно, в этом случае лямбда-выражение относится к некоему bump
, отличному от того, которое находится вместе со строкой его исходного кода.
Я хотел бы иметь возможность скомпилировать то, что мне кажется допустимым лямбда выражения, которые относятся к именам, соответствующим образом определенным в близлежащих контекстах. Можно ли заставить мой test_compile_with_lambda
работать без определения bump
каким-то неестественным образом?