根据例子逐个分析
顶层平行导入
- 见上一篇
- 见上一篇
- 见上一篇
- 见上一篇
- 在上面的基础上,我们增加调用
test()
函数的语句。从上面dir()
的结果看,如果按照import
导入时采用top.test()
方式调用,应该会报错,因为没有看到载入top
。
实际运行结果,抛出找不到top
的异常:
============== top.py ==============
Traceback (most recent call last):
File "E:\WorkSpace\Python\test\sound\test_main.py", line 5, in <module>
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
top.test()
NameError: name 'top' is not defined
[Finished in 0.2s with exit code 1]
采取直接调用test()
的方式,运行正常。
代码:
# 导入top
from top import test
test()
# test_mian.py原始内容
print "============== test_main.py =============="
print dir()
def test():
print "============== test_main.test =============="
# main()
if __name__ == '__main__':
test()
运行结果:
============== top.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
============== top.test ==============
============== test_main.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'test']
============== test_main.test ==============
[Finished in 0.2s]
-
名字空间问题。
上面的例子中,由test()
替代了之前的top.test()
。这会带来一个名字上的冲突,因为不仅top.py
有test()
函数,test_main.py
本身也有一个test()
函数。
6.1 从上面例子的运行结果看,在from top import test
后的test()
是调用的top.test()
, 在if __name__ == '__main__':
后面调用的test()
是test_main.test()
。
6.2 我们再修改一下上面的代码,将from top import test
后的test()
,放在def test()
的函数里面。
代码如下:
# 导入top
from top import test
# test_mian.py原始内容
print "============== test_main.py =============="
print dir()
def test():
print "============== test_main.test =============="
test()
# main()
if __name__ == '__main__':
test()
运行的结果是,挪动后test()
被认为是调用test_main.test()
,也就是说自己在递归调用自己。所以,打印的结果是无限循环,最后资源不够抛出异常。
运行结果(太长,省略中间内容)
============== top.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
============== test_main.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'test']
============== test_main.test ==============
============== test_main.test ==============
============== test_main.test ==============
============== test_main.test ==============
============== test_main.test ==============
中间重复打印
File "E:\WorkSpace\Python\test\sound\test_main.py", line 10, in test
test()
File "E:\WorkSpace\Python\test\sound\test_main.py", line 10, in test
test()
RuntimeError: maximum recursion depth exceeded
6.3 我们再把test()
挪一下,挪出def test():
函数体外,放在其下一行。
代码如下:
# 导入top
from top import test
# test_mian.py原始内容
print "============== test_main.py =============="
print dir()
def test():
print "============== test_main.test =============="
test()
# main()
if __name__ == '__main__':
test()
运行结果其实跟6.2
一样,test()
被认为是test_main.test()
。只是由于不是递归调用,所以就打印了一行而已。下面是运行结果:
============== top.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
============== test_main.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'test']
============== test_main.test ==============
============== test_main.test ==============
6.4 再次对代码进行改动,我们在6.3
的基础上,将from top import test
挪到def test()
函数和test()
之间。代码如下:
# test_mian.py原始内容
print "============== test_main.py =============="
print dir()
def test():
print "============== test_main.test =============="
# 导入top
from top import test
test()
# main()
if __name__ == '__main__':
test()
运行结果发现,test()
和__main_中的test()
都被认为是top.test()
,而不再是test_main.test()
。实际结果如下:
============== test_main.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
============== top.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
============== top.test ==============
============== top.test ==============
从实例情况来看,import
和def
都会覆盖原有的相同函数名。具体调用的是哪个,就看调用时哪个是最后一个被导入或者定义的。
顶层平行导入小结:
- 对于最顶层的同级文件互相导入时,
import m
和from m import f
均有效。只是import m
调用方式是m.f
,而from m import f
调用方式是f
。 - Python执行
import m
或from m import f
时,会将py文件编译成pyc,并且会执行全局的那些代码。 - 采取
from m import f
方式导入,可能会涉及到名字空间冲突问题。调用f
时,具体的调用对象,需要查看其往上最近的import
或def
对象确定。