2010-10-09 3 views
7

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

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

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» в памяти?

Нужно ли мне импортировать все в рамках каждого модуля, который мне нужен в этом модуле?

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

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

справка приветствуется.

Narnie

+0

По крайней мере, потому что вы не должны писать модули в предположении, что импортирующий модуль также импортировал определенный модуль. – delnan

ответ

13

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

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

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 является специфическим: оператор импорта действительно ничего не делает в текущем модуле, кроме как назначить модуль obje ct к указанному вами имени.Вот почему вы автоматически не получаете имена из импортированного модуля и почему это не похоже на копирование импортированного кода в текущий модуль.

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

+1

Этот пик «под капотом» помогает мне лучше понять, что происходит. Благодарю. – narnie

+0

спасибо @Ned Batchelder, ты поможешь мне сегодня. –

6

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

Некоторые подробнее: http://effbot.org/zone/import-confusion.htm

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

+0

Обратите особое внимание на то, что независимо от того, сколько раз вы импортируете модуль, код внешней области в импортированном модуле работает только один раз (запрет разгрузки и перезагрузки, конечно). OP не будет иметь 2 'gtk в памяти. Эффект последующего импорта заключается только в том, чтобы вносить вещи в локальное пространство имен. –

+0

Спасибо за разъяснение. Кажется, много «лишней» работы и немного отходов для этого, но если так оно и есть, так оно и есть. Спасибо за ссылку. Я только начал читать его, и я думаю, что это именно то, что мне нужно думать лучше на питоне. – narnie

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