我是Python新手,有一些事情困扰了我很长时间。我在marklutz的“Learning Python”中读到,当我们使用from
语句导入模块中存在的名称时,它首先导入模块,然后为其分配一个新名称(即导入模块中存在的函数、类等的名称),然后用del
语句删除模块对象。但是,如果我尝试使用from
导入一个名称,该名称引用了导入模块中本身未导入的名称,会发生什么情况?考虑下面的例子,其中有两个模块mod1.py
和mod2.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
模块对象。在
所以我基本上需要知道为什么这段代码能工作,即使考虑到我提到的那些不应该的问题
编辑:感谢所有回答:)
其他的答案比这一个更清楚,但是如果运行下面的程序,您可以看到}实际上都是在
countChars
和{test.__globals__
中定义的:您可以看到导入
test
会带来mod2
中定义的其他全局变量,这样您就可以运行函数而不必担心必须导入所需的所有内容。在我认为您正在努力解决python处理
namespaces
的方式。当您键入from module import thing
时,您将把thing
从module
带到当前命名空间中。因此,在您的示例中,当mod1
被导入时,将按以下顺序计算代码:现在对于mod2:
^{pr2}$所有这些之所以重要,是因为python允许您准确地选择要放入名称空间的内容。例如,假设您有一个
module1
,它定义函数cool_func
。现在您正在编写另一个模块(module2
),它使得module2
也有一个函数cool_func
。Python允许您将它们分开。在module3
中,您可以:或者,你可以:
或者你可以:
可能性还在继续。。。在
希望我的观点是清楚的。从模块导入对象时,您正在选择如何在当前命名空间中引用该对象。在
每个函数都有一个
__globals__
属性,该属性保存了搜索全局变量和函数的环境的引用。在然后,
test
函数链接到mod2
的全局变量。因此,当它调用countLines
时,即使您在导入函数的模块中编写了一个同名的新函数,解释器也总能找到正确的函数。在相关问题 更多 >
编程相关推荐