2011-02-02 3 views
8

Там это часть __import__ в документации на Python, который я не понимаю:Что такое параметры `globals` и` locals` в функции Python __import__?

__import__(name[, globals[, locals[, fromlist[, level]]]])

Функция импортирует модуль name, потенциально используя данный globals и locals, чтобы определить, как интерпретировать name в контексте пакета. Стандартная реализация не использует свой аргумент locals вообще и использует свой globals только для определения контекста пакета оператора импорта.

Что нужно для «толкования» имени модуля? Что такое контекст пакета?

Пример вызов с использованием этих параметров выглядит следующим образом:

spam = __import__('spam', globals(), locals(), [], -1) 

Почему пример обеспечивает globals() и locals() к функции? Что происходит, когда я предоставляю только globals()? Или нет?

Возможно, у меня есть часть логики пространства имен, связанная с импортом модулей. Не могли бы вы указать мне статью, которая объясняет это/имеет примеры с функцией __import__?

+1

Не следует ли переместить этот вопрос в StackOverflow? – EOL

+0

Это смешно, я начал писать это в SO, но думал, следует ли мне публиковать его на программистах.SE вместо этого ... Мне явно нужно посмотреть часто задаваемые вопросы ... –

+0

Вы должны выбрать один из следующих ответов в качестве принятый ответ на этот вопрос. ИМХО, ответ 9000 поражает гвоздь на голове, объясняя, что делает Python с 'globals', чтобы определить пространство имен модулей. – Kumba

ответ

4

Стандартная реализация не использует свой аргумент locals на всех, и использует его globals только определить контекст пакета в import заявлении.

(от docs.python.org)

Я до сих пор не имеют ни малейшего представления о том, как globals используются; какая глобальная переменная может повлиять на работу import?

EDIT: После просмотра import.c в Python 2.5 источника я обнаружил, что __import__ рассчитывает найти либо __name__ или __path__ в globals с целью усиления поиска импорта путь относительно пути (ы) в одном из этих переменных, в этой последовательности.

+0

Разговор о тупой. Таким образом, в основном вместо того, чтобы передавать этот массивный блок памяти вокруг всех глобальных переменных (предполагая, что Python не делает это по ссылке), можно просто передать dict с помощью одного ключа «__name __» ', установленного на вызывающий модуль '__name__', и Python будет работать с ним. Документацию Python следует обновить с помощью этой информации. – Kumba

+0

@ Kumba: предположим, что Python делает все по ссылке, за исключением некоторых примитивных числовых операций. Дикты определенно передаются по ссылке. Python 3.3 даже вводит реализацию dicts, которые используют общие ключи, то есть к ключам обращаются также по ссылке. Говорите о когерентности кэш-памяти, если вы хотите ворчать :) – 9000

+0

Фактически играя на (и владея) не кеш-когерентным оборудованием, я могу только представить себе этот кошмар. К счастью (или, к сожалению, возьмите ваш выбор), код, который я написал в Python, должен работать, по крайней мере, с Python 2.4. Я избегал 3.x, потому что я знаю, что это полностью перевернуло язык, и многие из моего кода, вероятно, не будут работать без серьезного переписывания. – Kumba

0

Что нужно для «толкования» имени модуля? Что такое контекст пакета?

При входе

>>> a 

Python должен "интерпретировать" это имя. Это глобальный? Это местный?

>>> def f(x): 
... return x * a 

В настоящее время x является явно локальным. a должен быть «интерпретирован». Глобальный? Местный?

Почему этот пример обеспечивает глобальные функции() и locals() для функции? Что происходит, когда я предоставляю только глобальные()?Или нет?

Попробуйте и посмотрите. Шутки в сторону. С ней легче играть, чем просить.

Важно то, что все, что вы делаете в приглашении >>>, является глобальным.

Вам нужно будет определить функции, которые создадут локальный контекст, чтобы вы могли видеть различия между глобальными и локальными.

+0

Хорошо, я немного поиграю :) –

+0

Смешная правда заключается в том, что импортируемый модуль игнорирует почти глобальные значения модуля, который выполняет импорт, а '__import__' полностью игнорирует параметр locals. В противном случае, вы правы :) – 9000

1

globals Используется для определения текущего контекста, на котором вызывается импорт. Например:

""" 
/myproject/a/b.py 
/myproject/a/foo.py 
/myproject/c/d.py 
/myproject/c/foo.py 
""" 

# Which foo gets imported? 

import foo #1 
foo = __import__('foo') #2 

Они не то же самое, так как нет (простой) способ на # 2, чтобы узнать, из какого модуля импорта вызывается из. Функция __import__ должна знать, какой текущий модуль фактически импортировать правильно foo.

Внутренне на __import__(), globals используется для получения ссылки на текущий модуль, вызывающий импорт. Из __import__source code:.

Возвращения пакета, что импорт выполняется, если глобал приходит из модуля foo.bar.bat (не сам пакет), это возвращает запись sys.modules для foo.bar. Если глобальные переменные из пакета init .py, возврат пакета в sys.modules возвращается в качестве заимствованной ссылки.

+0

Предположим, что '' import foo'' в 'b.py' и' d.py'. Как Python не знает, какой из них импортировать? В случае 'b.py', почему он ищет' foo' в '../c'/? –

+0

Если есть 'import foo' в'/myproject/e.py', это должно работать. Либо «import a.foo», либо «import c.foo». Извините ... Я не могу привести пример, который «вызовет проблемы», не могли бы вы дать мне подсказку? –

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