2015-01-22 3 views
3

От the documentation:Почему «из ... import *» в функции не разрешено?

дикая форма карты импорта - from module import * - допускается только на уровне модуля. Попытка использовать его в определениях классов или функций повысит значение SyntaxError.

Почему? В чем смысл избегать использования его в функции? В чем проблема?

ответ

8

Реализация CPython использует специальную оптимизацию для локальных переменных: Они не динамически посмотрели во время выполнения из словаря, а Глобал, а присвоены индексы статически в время компиляции и ищутся по индексу во время выполнения, что намного быстрее. Это требует, чтобы компилятор Python мог идентифицировать все локальные имена во время компиляции, что невозможно, если у вас есть подстановочный импорт на уровне функции.

В Python 2 был все еще резервный механизм, который вызывался в случаях, когда не всегда можно было установить все локальные имена статически. Этот механизм использовал динамический словарь для локальных переменных, что значительно замедляло выполнение.

Например, этот код

def f(): 
    exec "x = 2" 
    print x 

работы, как ожидается, в Python 2, в то время как

def f(): 
    exec("x = 2") 
    print(x) 

приводит к NameError в Python 3.

+0

Так что, если я получаю это право путь: во время компиляции, для локальных областей, Python находит все используемые переменные и сохраняет их в таблице; вместо этого для глобалов Python изменяет словарь, содержащий все глобальные имена во время выполнения. В функции мы не можем использовать подстановочный знак, потому что, используя Python статический механизм, тогда он должен найти и скомпилировать все модули, импортированные в функции и те модули, импортированные в эти модули. Это правильно? – zer0uno

+0

@antox: Да, это так. И поскольку глобальные переменные являются динамическими, их можно даже динамически создавать во время выполнения, например. путем изменения словаря 'globals()' или с помощью 'exec()', поэтому совершенно невозможно статически определить все имена, которые могут быть импортированы. –

+0

@sven_marnach Хорошо, только один вопрос. Вы сказали, что в Python2 они использовали двойной механизм, первый статический и второй динамический, как резерв. Разве они не могли использовать подобное поведение для глобалов? потому что я понимаю, что «статически» оптимизирует программу, поэтому они используют статическую стратегию, но если вы хотите сделать «exec (« x = 2 »), то двигатель опустится на вторую стратегию – zer0uno

Смежные вопросы