(упрощено из-за слишком многословного вопроса, который я написал ранее!)
Учитывая строку Python, содержащую действительный код Python, который содержит оператор yield, как я могу сгенерировать генератор, который исполняет эту строку?
Например, с учетом строки:
code_string = """for x in range(0, 10):
yield x
"""
Я хочу создать генератор f, который выполняет code_string так, чтобы (в этом конкретном примере):
assert(list(f()) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Обратите внимание, что code_string произвольно , поэтому это утверждение действительно только для приведенного выше примера. code_string может содержать любой допустимый код Python, который содержит оператор yield.
Спасибо!
Edit:
Первым решением, о котором я подумал, было просто ввести "def f ():" в строку и сделать программный отступ каждой строке. Однако это не работает, если code_string использует разные отступы. Я надеялся, что есть несколько малоизвестных functools кунг-фу, которые могут создать функцию из большого количества текста.
Edit2:
Я также попытался выполнить exec внутри функции, например:
code = "for x in range(0, 10): yield x"
def f():
exec code in globals(), locals()
Это приводит к "SyntaxError: 'yield' вне функции"
Решено: Я стою исправлено, отступ относительно, так что это работает:
code_string = """for x in range(0, 10):
yield x
"""
exec "def f():\n" + [(" " + line) for line in code_string.split('\n')]) + "\n"
assert list(f()) == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]