导入如何运作?为何导入的模块不继承其他导入模块

7 投票
2 回答
4133 浏览
提问于 2025-04-16 05:14

我之前以为我明白导入和模块是怎么回事,但显然我还需要更多的学习。

这里有一个示例程序(只是我正在做的一个更大项目的测试案例)和一个模块:

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?这是否意味着我内存中有两个“gtk”?

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

我知道每个模块都有自己的命名空间,但我以为它也会继承调用程序中的“全局”内容,包括导入的模块。

我一直以为从模块导入*就像把代码直接复制粘贴到那个位置。有没有其他方法可以做到这一点?

非常感谢你的帮助。

Narnie

2 个回答

6

要把一个.py文件里的内容引入到当前模块中,就必须使用import。如果不使用import,里面的名字就无法被引用。

更多信息可以查看这个链接:http://effbot.org/zone/import-confusion.htm

当Python导入一个模块时,它会先检查模块注册表(sys.modules),看看这个模块是否已经被导入过。如果已经导入,Python就会直接使用现有的模块对象。

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的赋值是特定的:导入语句在当前模块中实际上并不会做什么,除了把一个模块对象赋值给你指定的名称。这就是为什么你不会自动获得导入模块中的名称,也为什么这并不是把导入的代码复制到当前模块里。

另外,在import_module这个伪函数中,如果某个名称已经在其他地方被导入过,它会在所有模块的全局列表中(sys.modules),所以会直接被重用。文件不会再次打开,也不会再次执行,该模块中的全局变量也不会再获得新值,等等。将同一个模块导入多个地方并不是浪费或额外的工作,这个过程非常快。

撰写回答