导入如何工作.为什么导入的模块不继承其他导入的模块

nar*_*nie 7 python import module

我只是"想"我理解导入和模块是如何工作的,但显然我需要更多的学校教育.

这是一个示例程序(只是一个测试案例,我正在做的事情,范围和规模要大得多)和一个模块:

quick.py

import gtk
from quick_window import *

w.show_all()
gtk.main()
Run Code Online (Sandbox Code Playgroud)

quick_window.py

w = gtk.Window()
w.connect('destroy', lambda w: gtk.main_quit())
l=gtk.Label('Hello')
w.add(l)
Run Code Online (Sandbox Code Playgroud)

我跑了

$ 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
Run Code Online (Sandbox Code Playgroud)

为了使它工作,我还必须在模块中导入(呃,重新导入)gtk,如下所示:

import gtk

w = gtk.Window()
w.connect('destroy', lambda w: gtk.main_quit())
l=gtk.Label('Hello')
w.add(l)
Run Code Online (Sandbox Code Playgroud)

我为什么要多次导入gtk?这是否意味着我在内存中有2个"gtk's"?

我是否必须在该模块中导入我需要的每个模块中的所有内容?

我知道每个模块都有自己的命名空间,但我认为它还继承了"全局",包括来自调用程序的导入模块.

我一直认为from module import*就像将代码剪切并粘贴到该位置一样.还有另一种方法吗?

非常感谢帮助.

Narnie

Ned*_*der 13

导入的细节变得非常复杂,但从概念上讲它非常简单.

当你写:

import some_module
Run Code Online (Sandbox Code Playgroud)

它相当于:

some_module = import_module("some_module")
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

这里需要注意两点:some_module的赋值是特定的:除了将模块对象分配给您指定的名称外,import语句在当前模块中什么都不做.这就是为什么你不自动从导入的模块中获取名称,以及为什么它不像将导入的代码复制到当前模块中.

此外,在import_module伪函数中,如果名称已经在某处导入,它将位于所有模块的全局列表中(sys.modules),因此只需重复使用.该文件不会再次打开,也不会再次执行,该模块中的全局变量不会再次获取新值,依此类推.将同一模块导入许多地方并不浪费或额外工作,速度非常快.


Jef*_*emp 6

需要导入才能将py文件的内容带入该模块的命名空间 - 如果不导入,则无法引用其中的名称.

更多信息:http://effbot.org/zone/import-confusion.htm

当Python导入模块时,它首先检查模块注册表(sys.modules)以查看模块是否已导入.如果是这种情况,Python会按现有模块对象使用.