У меня есть (как мне кажется) некоторое базовое понимание правил области видимости Python (на основе изучения этот ответ).
Я также узнал из документация на exec, что он принимает globals и locals в качестве необязательных аргументов, и что:
In all cases, if the optional parts are omitted, the code is executed in the current scope.
ПРИМЕЧАНИЕ: все приведенные ниже примеры предполагают использование Python 3.
С учетом сказанного, недавно я наткнулся на этот случай, который меня немного смутил:
def test(passed_data):
local_result = 5
exec("print(passed_data)")
exec("print(local_result)")
return local_result
print (test('whatever'))
выполнение приведенного выше кода приводит к:
whatever
5
5
Здесь очевидно, что exec имеет доступ к локальным пользователям test (passed_data и local_result).
Хотя, если мы попробуем изменить любой из них:
def test(passed_data):
local_result = 5
exec("print(passed_data)")
exec("print(local_result)")
exec("passed_data = 222")
exec("local_result = 111")
exec("print(passed_data)")
exec("print(local_result)")
return local_result
print (test('whatever'))
это приведет к:
whatever
5
whatever
5
5
Использование global внутри exec:
def test(passed_data):
local_result = 5
exec("print(local_result)")
exec("global local_result; local_result = 111")
exec("print(local_result)")
return local_result
print (test('whatever'))
дает тот же результат (конечно, поскольку local_result является локальным для test):
5
5
5
Что позволяет нам проверить local_result через exec - это определить его с помощью global:
def test(passed_data):
global local_result
local_result = 5
exec("print(local_result)")
exec("global local_result; local_result = 111")
exec("print(local_result)")
return local_result
print (test('whatever'))
Это дает нам:
5
111
111
Мне кажется, что мне просто не хватает базового понимания области видимости Python или механики exec, чтобы разобраться в этом случае.
Тем не менее, я хотел бы понять следующее:
exec может печатать переменную из области действия функции без использования global, но не может ее изменить?globals и locals опущены) exec будет выполнять любой код Python в той области, из которой он вызывается, как если бы этот код был только в источнике (без exec), где (и как) я ошибаюсь в этом предположении?P.S .: Я понимаю, что изменение локальной переменной через exec - это «неправильный поступок», я ищу понимание правил области видимости exec просто ради обучения.
Оформить заказ на этот ответ Я только что отправил stackoverflow.com/a/49208472/2867928
@AlexHall, спасибо, что указали на соответствующий раздел документации!
@Kasramvd, я проверил ваш ответ - он действительно объясняет то же самое. Спасибо!






Локальные переменные подлежат оптимизации, которая предотвращает их динамическое изменение. Аналогичным примером является примечание в docs.python.org/3/library/functions.html#locals. Глобальные переменные не имеют этих ограничений, но для того, чтобы компилятор распознал переменную как глобальную, а не как локальную, требуется оператор
globalвне exec.