Добавление `exec" pass "` к функции позволяет отражать модификации locals () в пространстве имен? - PullRequest
2 голосов
/ 02 ноября 2011

Читая ответ на вопрос, В чем разница между globals (), localals () и vars ()? , было дано следующее объяснение того, как locals() работает:

если внутри функции вызывается locals (), он создает словарь пространства имен функций на тот момент и возвращает его - любые дальнейшие присвоения имен не отражаются в возвращаемом словаре, и любые присвоения словарюне отражено в фактическом локальном пространстве имен

В комментарии было упомянуто, что

Часть "и любые присвоения словарю не отражаются в фактическом локальном пространстве имен"может быть сформулирован немного определенно.

со ссылкой на следующий код:

def f():
    exec "pass"
    locals()["x"] = 42
    print(x)
f()

Возвращает 42 (по крайней мере в CPython 2.7).Без строки exec "pass" python выдает NameError, потому что не может найти 'x'.Это согласуется с определением, что изменения в словаре, возвращаемом locals() внутри функции, не отражаются в пространстве имен.Почему добавление строки exec "pass" позволяет отражать эти изменения?Это как-то обманывает питона, заставляя его думать, что он возбудил функцию?

1 Ответ

3 голосов
/ 02 ноября 2011

Этот ответ на другой вопрос имеет хорошее объяснение того, что происходит. Вот резюме:

Наличие оператора exec приводит к тому, что Python 2 компилирует f совершенно неоптимизированным образом, поэтому локальные данные находятся в dict, а не в массиве, как обычно. (Производительность может быть значительной).

...