Iso*_*toR 6 python import module
我是Python的新手,而且有一段时间以来一直困扰着我的东西.我在Mark Lutz的"学习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
Run Code Online (Sandbox Code Playgroud)
现在看看当我运行或导入mod1时会发生什么:
>>>import mod1
loading...
3
44
----------
Run Code Online (Sandbox Code Playgroud)
这里当我导入并运行该test函数时,它成功运行,虽然我甚至没有导入countChars或countLines,并且该from语句已经删除了mod2模块对象.
所以我基本上需要知道为什么这个代码工作,即使考虑到我提到的问题不应该.
编辑:Thanx很多人回答:)
每个函数都有一个__globals__属性,该属性包含搜索全局变量和函数的环境的引用.
test然后该函数链接到全局变量mod2.因此,当它调用时,countLines即使您在导入函数的模块中编写了一个具有相同名称的新函数,解释器也始终会找到正确的函数.
我认为你正在努力解决 python 处理的方式namespaces。当您键入时,from module import thing您正在将thingfrommodule引入当前的命名空间。因此,在您的示例中,mod1导入时,代码将按以下顺序求值:
from mod2 import test #Import mod2, bring test function into current module namespace
test("mod1.py") #run the test function (defined in mod2)
Run Code Online (Sandbox Code Playgroud)
现在对于 mod2:
#create a new function named 'test' in the current (mod2) namespace
#the first time this module is imported. Note that this function has
#access to the entire namespace where it is defined (mod2).
def test(name):
print 'loading...'
countLines(name)
countChars(name)
print '-'*10
Run Code Online (Sandbox Code Playgroud)
所有这些之所以重要,是因为 python 可以让您准确选择要拉入命名空间的内容。例如,假设您有一个module1which 定义了 function cool_func。现在你正在编写另一个模块(module2),它使得 for也module2有一个函数cool_func。Python 允许您将它们分开。module3你可以这样做:
import module1
import module2
module1.cool_func()
module2.cool_func()
Run Code Online (Sandbox Code Playgroud)
或者,你可以这样做:
from module1 import cool_func
import module2
cool_func() #module1
module2.cool_func()
Run Code Online (Sandbox Code Playgroud)
或者你可以这样做:
from module1 import cool_func as cool
from module2 import cool_func as cooler
cool() #module1
cooler() #module2
Run Code Online (Sandbox Code Playgroud)
可能性还在继续......
希望我的观点很清楚。当您从模块导入对象时,您正在选择如何在当前命名空间中引用该对象。
| 归档时间: |
|
| 查看次数: |
189 次 |
| 最近记录: |