Как работает импортПочему импортированные модули не наследуют другие импортированные модули - PullRequest
7 голосов
/ 09 октября 2010

Я просто «подумал», что понял, как работают импорт и модули, но, очевидно, мне нужно больше учиться.

Вот пример программы (просто тестовый пример того, что я делаю, и который гораздо больше по объему)и масштаб) и модуль:

quick.py

import gtk
from quick_window import *

w.show_all()
gtk.main()

quick_window.py

w = gtk.Window()
w.connect('destroy', lambda w: gtk.main_quit())
l=gtk.Label('Hello')
w.add(l)

работает Я получаю

$ python quick.py
Traceback (most recent call last):
  File "quick.py", line 2, in <module>
    from quick_window import *
  File "/home/woodnt/Dropbox/python/weather_project/plugins/quick_window.py", line 3, in <module>
    w = gtk.Window()
NameError: name 'gtk' is not defined

Кчтобы заставить его работать, я должен также импортировать (э-э, реимпортировать) gtk в модуль следующим образом:

import gtk

w = gtk.Window()
w.connect('destroy', lambda w: gtk.main_quit())
l=gtk.Label('Hello')
w.add(l)

Почему я должен импортировать gtk более одного раза?Означает ли это, что у меня есть 2 "gtk's" в памяти?

Должен ли я импортировать все внутри каждого модуля, что мне нужно в этом модуле?

Я знаю, что каждый модуль имеет свое собственное пространство имен,но я думал, что он также унаследовал «глобальные переменные», включая импортированный модуль, от вызывающей программы.

У меня сложилось впечатление, что импорт из модуля * подобен вырезке и вставке кода прямо в это место.Есть ли другой способ сделать это?

Помощь очень ценится.

Нарни

Ответы [ 2 ]

13 голосов
/ 09 октября 2010

Детали импорта становятся очень сложными, но концептуально это очень просто.

Когда вы пишете:

import some_module

Это эквивалентно этому:

some_module = import_module("some_module")

где import_module вроде как:

def import_module(modname):
    if modname in sys.modules:
        module = sys.modules[modname]
    else:
        filename = find_file_for_module(modname)
        python_code = open(filename).read()
        module = create_module_from_code(python_code)
        sys.modules[modname] = module
    return module

Здесь следует отметить две вещи: назначение some_module является специфическим: оператор import действительно ничего не делает в текущем модуле, кроме как присваивает объекту модуля указанное вами имя. Вот почему вы не получаете автоматически имена из импортированного модуля, и это не похоже на копирование импортированного кода в текущий модуль.

Кроме того, в псевдофункции import_module, если имя уже где-то импортировано, оно будет в глобальном списке всех модулей (sys.modules) и поэтому просто будет использовано повторно. Файл не будет снова открыт, он не будет выполнен снова, глобальные переменные в этих модулях не получат новые значения снова, и так далее. Импортирование одного и того же модуля во многие места не является расточительством или дополнительной работой, это очень быстро.

6 голосов
/ 09 октября 2010

import требуется для переноса содержимого файла py в пространство имен этого модуля - если вы не импортируете, на имена в нем нельзя ссылаться.

Дополнительная информация: http://effbot.org/zone/import-confusion.htm

Когда Python импортирует модуль, он сначала проверяет реестр модуля (sys.modules), чтобы увидеть, если модуль уже импортировано. Если это так, Python использует существующий объект модуля как есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...