关于Python中导入的一些混淆

2024-09-28 21:12:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我是Python新手,有一些事情困扰了我很长时间。我在marklutz的“Learning Python”中读到,当我们使用from语句导入模块中存在的名称时,它首先导入模块,然后为其分配一个新名称(即导入模块中存在的函数、类等的名称),然后用del语句删除模块对象。但是,如果我尝试使用from导入一个名称,该名称引用了导入模块中本身未导入的名称,会发生什么情况?考虑下面的例子,其中有两个模块mod1.pymod2.py

#mod1.py
from mod2 import test
test('mod1.py')        

#mod2.py
def countLines(name):
    print len(open(name).readlines())

def countChars(name):
    print len(open(name).read())

def test(name):
    print 'loading...'
    countLines(name)
    countChars(name)
    print '-'*10

现在看看运行或导入mod1时会发生什么:

^{pr2}$

在这里,当我导入并运行test函数时,虽然我甚至没有导入countChars或{},但它还是成功地运行了,from语句已经删除了mod2模块对象。在

所以我基本上需要知道为什么这段代码能工作,即使考虑到我提到的那些不应该的问题

编辑:感谢所有回答:)


Tags: 模块对象函数namefrompytest名称
3条回答

其他的答案比这一个更清楚,但是如果运行下面的程序,您可以看到countChars和{}实际上都是在test.__globals__中定义的:

from pprint import pprint
from mod2 import test

pprint(test.__globals___)
test('mod1')

您可以看到导入test会带来mod2中定义的其他全局变量,这样您就可以运行函数而不必担心必须导入所需的所有内容。在

我认为您正在努力解决python处理namespaces的方式。当您键入from module import thing时,您将把thingmodule带到当前命名空间中。因此,在您的示例中,当mod1被导入时,将按以下顺序计算代码:

from mod2 import test #Import mod2, bring test function into current module namespace
test("mod1.py")  #run the test function (defined in mod2)

现在对于mod2:

^{pr2}$

所有这些之所以重要,是因为python允许您准确地选择要放入名称空间的内容。例如,假设您有一个module1,它定义函数cool_func。现在您正在编写另一个模块(module2),它使得module2也有一个函数cool_func。Python允许您将它们分开。在module3中,您可以:

import module1
import module2
module1.cool_func()
module2.cool_func()

或者,你可以:

from module1 import cool_func
import module2 
cool_func() #module1
module2.cool_func()

或者你可以:

from module1 import cool_func as cool
from module2 import cool_func as cooler
cool()  #module1
cooler() #module2

可能性还在继续。。。在

希望我的观点是清楚的。从模块导入对象时,您正在选择如何在当前命名空间中引用该对象。在

每个函数都有一个__globals__属性,该属性保存了搜索全局变量和函数的环境的引用。在

然后,test函数链接到mod2的全局变量。因此,当它调用countLines时,即使您在导入函数的模块中编写了一个同名的新函数,解释器也总能找到正确的函数。在

相关问题 更多 >