Python: переменная, определенная exec(), не определена в области действия функции

Рассмотрим следующий код

g = {}
l = {}

exec("a = 1", g, l)
exec("""
def test():
    print(a)
""", g, l)

l['test']()

Это приводит к

$ python test.py
Traceback (most recent call last):
  File "test.py", line 12, in <module>
    l['test']()
  File "<string>", line 3, in test
NameError: name 'a' is not defined

Кажется, это происходит только тогда, когда я использую отдельные словари для глобальных и локальных переменных. Если я вместо этого использую g = l = {}, он работает так, как ожидалось.

Почему переменная, определенная первым exec, недоступна в функции, определенной вторым exec?

Стоит отметить, что переменная заканчивается на l, а не на g.

Это похоже на Как exec работает с местными жителями?, за исключением того, что это не совсем то же самое, потому что здесь я использую настоящий словарь для locals.


person asmeurer    schedule 21.09.2017    source источник
comment
Урок, который необходимо усвоить, состоит в том, чтобы не использовать exec или eval.   -  person cs95    schedule 22.09.2017
comment
Краткий ответ: globals и locals должны быть одним и тем же сопоставлением, чтобы действовать так, как если бы вы выполнялись в области уровня модуля. Если вы передаете два разных сопоставления, оно выполняется как определение класса. Точно так же, как если бы вы определили a = classvar в блоке класса, методы не будут иметь доступа к a .   -  person juanpa.arrivillaga    schedule 22.09.2017
comment
@juanpa.arrivillaga, ты должен был написать это как ответ. Это настолько ясно, насколько это возможно.   -  person asmeurer    schedule 22.09.2017