模块与包是任何大型程序的核心,就连 Python 安装程序本身也是一个包。
封装成包
为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package),包是模块的集合,比模块又高一级的封装。
在文件系统上组织你的代码,并确保每个目录都定义了一个init.py 文件。
dirs/
__init__.py
dir_sons/
__init__.py
sus.py
text.py
文件_init_.py的作用:包含不同运行级别的包的可选的初始化代码。通常__init__.py 文件为空,但是我们还可以为它增加其他的功能。我们在导入一个包时,实际上是导入了它的__init__.py文件。这样我们可以在__init__.py文件中批量导入我们所需要的模块,而不再需要一个一个的导入。
# package
# __init__.py
import re
import urllib
import sys
import os
# a.py
import package
print(package.re, package.urllib, package.sys, package.os)
import * 理论上是希望文件系统找出包中所有的子模块,然后导入它们。
But 会花长时间,并出现边界效应等。Python 解决方案是提供一个明确的包索引。
# __init__.py
__all__ = ['os', ‘re’,''sys]
# test.py
from package import *
import在此时会把init文件中的所有模块导入进来。
import检索顺序
import导入一个模块,Python解析器对模块位置的搜索顺序是:
- 当前目录
- 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
- 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
- 模块搜索路径存储在system模块的sys.path变量中。
如果想要将一个模块中的内容全部导入,可以使用 ‘from 模块名 import *’,想要对导入的内容进行精确控制,就需要在模块中定义一个变量 **all**来指定可以被导入的内容,但是十分不建议使用’from 模块 import *’。
模块制作与发布
在执行函数时,经常见到这个语句:
if __name__=='__main__':
pass
这句话的作用是什么呢?
在python中,所有py文件都可以被当作模块导入,而在导入时,解释器会默认执行该模块产生输入输出,这不是我们想要的,要解决这个问题,就需要用到个特殊变量 name。
可以根据__name__变量的结果能够判断出,是直接执行的python脚本还是被引入执行的,如果是被导入的,就不执行模块。反之则执行。
模块发布
如果想要将自己写的模块分享出去供大家使用,
- 为模块文件创建一个文件夹,并将模块文件复制到这个文件中(一般,文件夹的名字和模块的名字一样)
- 在文件夹中创建一个名为『setup.py』的文件:
最后加入:py_modules=[你需要发布的模块名, 不需要.py]发布过程:
. 向PyPI上传代码
python setup.py register
python setup.py sdist upload