Python模块与包使用实践
一. 定义
- 模块 : 一个
.py
文件就是一个模块(module),去除.py
后缀的文件名就是模块名。 - 包 :
__init__.py
文件所在目录就是包(package),目录名称就是包名称。
二. 两种形式的 import
import ...
from ... import ...
第一种import
后面只能是模块名、包名。
第二种from
后面只能是模块名、包名。import
后面可以是任何变量。
三. import 的搜索路径
当导入模块时,Python解释器会按照一定的顺序去搜索导入的模块,搜索顺序如下:
- 搜索「内置模块」(built-in module)。
- 搜索
sys.path
列表中的路径 。sys.path
中的路径也有顺序:
.py
文件所在目录,如果是软链接,则是真正的.py
所在目录;- 环境变量
PYTHONPATH
中列出的目录(export PYTHONPATH=/selfpath
); - 安装的第三方模块。
四. Python -m 参数
module_a.py 文件内容如下:
# module_a.py
import sys
print(__name__)
print(sys.path)
- 加
-m
参数表示以模块的方式运行,同时要去掉.py
后缀。 - 不加
-m
的方式表示直接运行。
[root@aliyzy pytest]# python -m module_a
__main__
['', '/usr/local/python2.7/lib/python2.7/site-packages/pip-9.0.1-py2.7.egg', .......]
[root@aliyzy pytest]# python module_a.py
__main__
['/root/pytest', '/usr/local/python2.7/lib/python2.7/site-packages/pip-9.0.1-py2.7.egg', .......]
区别在于:
- 前者的
sys.path
会添加当前工作目录到搜索路径。 - 后者的
sys.path
会添加.py
文件所在路径到搜索路径。
五. 相对import与绝对import
相对 import
在模块之间的调用时使用相对路径。使用相对路径来调用模块时,该脚本文件不能直接执行。
from ... import module_a
...
表示上上层目录, ..
表示上次目录, .
表示当前目录。
绝对 import
如果一个模块被直接运行,则其没有包结构,其 __name__
值为 __main__
,而不是模块原本的名字,所以使用相对导入的方式(from ...
)
六. 将目录加入sys.path
这样就可以避免将路径硬编码到代码中。
import sys
from os.path import abspath, join, dirname
sys.path.insert(0, join(abspath(dirname(__file__)), 'src'))
七. 模块使用 __all__ 变量
将本模块可以导出的函数、变量写到变量__all__
里面,可以避免别人使用你的模块时,使用from modelname import *
这种用法,导入了不该被导入的变量,可以指定导入__all__
所指定的模块。
# mytest.py
__all__= ['p', 'x']
name = 'yuchaoshui'
def p():
print('p')
def x():
print('x')
该模块如果被其他模块使用from mytest import *
导入的话,则只能导入p、x
这两个函数。