概述
基于官方指南的6. Modules进行学习的
https://docs.python.org/2/tutorial/modules.html#tut-standardmodules
根据例子逐个分析
例子思路
- 根据原理的描述找包或者模块时,系统先去找bulid-in,再在系统的python环境变量下找第三方的包文件,然后再找其他的。
这里我们只研究自己需要导入的包和模块的关系。 - 如果找自己的包或者模块,是先在平级目录找,然后再顺着找下级目录。
- 从上面的初步原理看,例子结构设计如下:
sound/
__init__.py
top.py
test_main.py
effects/
__init__.py
echo.py
surround.py
third/
__init__.py
third1.py
formats/
__init__.py
wavread.py
- 三层目录结构,顶层是
sound
;中间是'effects'和formats
;第三层是在effects
目录下增加一层third
目录。 - 每层均包含一个
__init__.py
文件,文件初始内容如下:
print "============== sound.__init__ =============="
print dir()
- 主执行文件是
test_main.py
,初始内容如下:
print "============== test_main.py =============="
print dir()
def test():
print "============== test_main.test =============="
if __name__ == '__main__'
test()
- 其他的文件基本内容如下:
print "============== surround.py =============="
print dir()
def test():
print "============== surround.test =============="
echo.py
比其他的多了一个test1函数,函数内容跟test一模一样,就是名字有变化。
- 实验的思路是,先在顶层平行导入,再向下导入(包括越级);再从下往上导入;最后是验证二层平行目录下的文件导入。
顶层平行导入
就是sound
目录下,test_main.py
导入并调用top.py
的函数。
- 在
test_main.py
中,直接调用top.test()
会抛出异常,运行结果如下:
============== test_main.py ==============
Traceback (most recent call last):
File "E:\WorkSpace\Python\test\sound\test_main.py", line 6, in <module>
top.test()
NameError: name 'top' is not defined
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
[Finished in 0.2s with exit code 1]
- 去掉调用
top.test()
的代码,加上import top
,也就是只导入不调用。
我们会发现,代码在导入时就已经执行了top的全局代码,而且多出了一个编译后的top.pyc文件。
另外一个变化是test_main.py的dir()输出,多了一个导入的top元素。
修改后的代码:
# 导入top
import top
# 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__']
============== test_main.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'top']
============== test_main.test ==============
[Finished in 0.2s]
- 我们在第2步的基础上,增加
top.test()
的调用,可以正常运行。
运行结果:
============== top.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__']
============== top.test ==============
============== test_main.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'top']
============== test_main.test ==============
[Finished in 0.2s]
- 我们将第上面的
import top
替换成from top import test
。我们先删除调用test()
函数的代码,先仅仅实验一下导入的情况。
基础代码如下:
# 导入top
from top import 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__']
============== test_main.py ==============
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'test']
============== test_main.test ==============
[Finished in 0.2s]
从运行结果看,跟import top
方式导入结果基本一致。唯一区别的地方在于dir()显示,from方式导入的是test,并没有导入top;而import方式导入的是top,而没有top下面的test。
另外,如果是from xx import *
方式的话,top里面有多少函数或者类都会载入。
内容太长,网页无法保存,所以强行拆分成几篇文章记录
网友评论