Реализация CPython использует специальную оптимизацию для локальных переменных: Они не динамически посмотрели во время выполнения из словаря, а Глобал, а присвоены индексы статически в время компиляции и ищутся по индексу во время выполнения, что намного быстрее. Это требует, чтобы компилятор Python мог идентифицировать все локальные имена во время компиляции, что невозможно, если у вас есть подстановочный импорт на уровне функции.
В Python 2 был все еще резервный механизм, который вызывался в случаях, когда не всегда можно было установить все локальные имена статически. Этот механизм использовал динамический словарь для локальных переменных, что значительно замедляло выполнение.
Например, этот код
def f():
exec "x = 2"
print x
работы, как ожидается, в Python 2, в то время как
def f():
exec("x = 2")
print(x)
приводит к NameError
в Python 3.
Так что, если я получаю это право путь: во время компиляции, для локальных областей, Python находит все используемые переменные и сохраняет их в таблице; вместо этого для глобалов Python изменяет словарь, содержащий все глобальные имена во время выполнения. В функции мы не можем использовать подстановочный знак, потому что, используя Python статический механизм, тогда он должен найти и скомпилировать все модули, импортированные в функции и те модули, импортированные в эти модули. Это правильно? – zer0uno
@antox: Да, это так. И поскольку глобальные переменные являются динамическими, их можно даже динамически создавать во время выполнения, например. путем изменения словаря 'globals()' или с помощью 'exec()', поэтому совершенно невозможно статически определить все имена, которые могут быть импортированы. –
@sven_marnach Хорошо, только один вопрос. Вы сказали, что в Python2 они использовали двойной механизм, первый статический и второй динамический, как резерв. Разве они не могли использовать подобное поведение для глобалов? потому что я понимаю, что «статически» оптимизирует программу, поэтому они используют статическую стратегию, но если вы хотите сделать «exec (« x = 2 »), то двигатель опустится на вторую стратегию – zer0uno