python模块与包
在Python中,一个扩展名为.py的文件就称之为一个模块,通常情况下我们将实现某一特定功能的代码放入一个文件中作为一个模块,从而方便其他程序和脚本导入使用,其次,使用模块也可以避免函数名和变量名重复,使用模块可以提高代码的可重用性,编写好模块后,只要实现此功能的程序,都可以导入该模块来实现。
一、自定义模块:
在Python中,自定义模块有两个作用:一是规范代码,二是供其他程序调用,提高开发效率。
实现自定义模块主要分为两部分:一是创建模块,二是导入其他模块。
1、创建模块:
创建模块的时候,可以将模块中的相关代码(函数定义和变量定义)编写在一个单独文件中,并将该文件命名为”模块名.py”的形式。
注意:创建模块名时,名称不能是Python中自带的标准模块名称,模块文件的扩展名必须是.py
例如:定义一个计算bmi的模块,如图:

2、使用import语句导入模块
创建模块后,就可以在其他程序中导入并使用该模块了,通过import语句导入,语法格式如下:
import modulename as alias
参数说明:
- modulename:表示模块名,模块名就是文件名,如:test.py,模块名就是test
- as alias:表示设置的别名,通过别名也可以使用模块,根据需要选择是否使用,非强制
例如:定义bmi模块(文件名为bmi.py),其中内容有harvest函数,如图:

在定义一个模块new.py,在内部调用bmi模块(两个模块需要在同一目录下),如图:

说明:在调用模块中的函数、变量、类的时候,需要在函数、变量和类前面加模块名作为前缀,上图中的bmi就是模块名,表示调用其中的harvest函数
如果模块名比较长不容易记住,可以在导入模块的时候指定别名,然后通过别名进行调用,如上面的导入bmi模块的时候就可以设置别名,然后通过别名调用,如图:

说明:使用import还可以一次导入多个模块,多个模块之间使用逗号分隔,但是不推荐这种方法,最好每个模块分别导入一次
导入模块的时候,解释器主要在三个位置搜索模块:
- 当前工作目录,解释器认为目前所在的文件夹
- 解释器的site-packages位置,里面包含已经安装的第三方模块或自己写的模块
- 标准库中的模块
3、使用from…import语句导入模块中的内容:
在使用import语句导入模块的时候,每执行一次import语句都会创建一个新的命名空间(namespace),在此命名空间中执行与.py文件相关的所有语句,并且在执行的时候需要在具体的函数名、变量、类名前加模块名作为前缀,如果不想在每次导入模块的时候都创建一个新的命名空间,而是将具体的定义导入到当前的命名空间中,这时可以使用from….import语句导入,导入后不再需要模块名作为前缀,可直接使用具体的变量、函数名、类名访问即可。
说明:命名空间可以理解为记录对象名字和对象之间关系的空间,python命名空间大部分通过字典来实现的,其中key 是标识符,value表示具体的对象,例如:key表示变量,value表示变量的值。
from….import的语法格式如下:
from modulename import number as alias #如果导入所有就是from modulename import *
参数说明:
- modulename表示模块名,也就是文件名
- number表示要导入具体的变量、函数和类名等,可以同时导入多个定义,多个定义之间使用逗号分隔,如果要导入全部定义,可以使用通配符*代替
- alias:指定别名,如果导入的名称与现有的冲突或者太长即可设置别名,非强制
例如:上图中例子从bmi模块中导入harvest函数,并直接调用,如图:

说明:在使用from…import语句导入模块中的定义时,要保证所导入的内容在当前的命名空间中是唯一的,否则会出现冲突,后导入的同名变量、函数、类会覆盖之前导入的,这时候就需要使用import语句导入(每次import都会创建新的命名空间)
使用import语句导入模块时,模块名时区分大小写的
4、以主程序的形式执行:
定义一个模块bmi.py,在模块中定义全局变量,定义problem()函数,如图:

在同级目录下定义文件new.py 并导入模块bmi模块,并输出全局变量的var值,如图:

打印结果如下:

从打印结果可以看出,我们只想打印 ”你好,世界“,但结果不只是全局变量的值,还打印出来很多其他内容,这并不是我们想要的,那么如果只输出全局变量的值呢,可以通过if语句判断是否以主程序方式执行,并将其他语句加入到if语句中,修改bmi.py文件,如图:

再次执行结果如下:

从上图可以看出,程序只获取了全局变量var,其余的内容都没有执行
说明:在每个模块的定义中都包含一个记录模块名称的变量__name__,程序可以检查该变量,以确定他们在哪个模块中执行,如果一个模块不是被导入到其他程序中执行,那么他可能在解释器的顶级模块中执行,顶级模块中的__name__变量的值为__main__
总结:__name__ == "__main__"函数是用来控制python文件执行的场景,使用该函数的最大作用就是为了控制该函数下面的语句在其他文件中导入时不执行效果,只能在本脚本中执行
二、Python中的包
使用模块可以避免函数名和变量名重名引发的冲突,那么如果模块名重复了怎么办呢?在Python中提出了包的概念,包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下,这样就可以避免模块名重复。
说明:包简单理解就是一个文件夹,只不过在该文件夹下必须存在一个名称为__init__.py的文件
1、创建和使用包:
创建包实际就是创建一个文件夹,并且在该文件夹中创建一个名称为__init__.py的Python文件,此文件可以不编写任何代码,也可以编写代码,编写的代码在导入包的时候会自动执行。
例如:在/data/pyproject目录下新建文件夹linshi,在linshi文件夹中创建文件__init__.py,此时linshi就是一个包了,如图:

在linshi包中新建gong.py文件,内容如图:

在包linshi的同级目录下创建文件b.py,从包linshi中导入模块gong,如图:

注意:实际上gong.py的名字就是模块名,通过模块名调用模块中的类
运行b.py,打印结果如下:

2、导入包:
创建包以后就可以在包中创建相应的模块,然后在使用import从包中加载模块,从包中加载模块的方法有以下三种:
第一种:通过import + 完整包名+模块名
例如:在包gong下有一个模块size,要导入此模块,语法如下:
import gong.size
调用模块后,如果要使用其中的变量,此时需要使用包名和模块名作为前缀
例如,在包名gong下的模块size中定义两个变量,在包名的同级目录下创建模块yi.py,导入size模块后,调用变量,如图:


第二种:通过from +完整包名+import+模块名,语法格式如下:
from gong import size
通过此种方法导入后,在使用的时候,不需要带包前缀,只需要使用模块名即可。
例如:上图中的例子,在yi.py中通过from导入包gong中的size模块,如图:

第三种:通过from+完整包名+模块名+import+定义名形式加载指定模块,语法格式如下:
from gong.size import weight #weight可以是变量、函数、类名
通过此种方法导入后,在使用的时候,可以不用加包名和模块名作为前缀,直接使用变量名、函数、类名即可,如图:

如果要导入多个定义,可直接使用*代替即可
三、引用其他的模块
1、导入和使用标准模块:
在Python中,定义了很多实用的模块,称为标准模块(标准库),对于标准模块,可直接使用Import导入即可使用,例如导入模块random,用于生成随机数,如下:
import random
说明:在导入标准模块时,也可以使用as关键字为其指定别名,通常情况下,如果模块名较长可以设置别名,并用别名访问内部属性。
如果要查看Python中含有哪些模块(内置模块和第三方模块),可以在IDE中输入help(‘modules’),如果只是查看安装了哪些第三方模块,可以使用pip list查看
四、第三方模块下载和安装
在Python程序开发的时候,除了可以使用内置模块外,还可以使用第三方模块,对于第三方模块,可以在http://pypi.python.org/pypi中找到,下载和安装第三方模块可以使用pip 命令实现,语法格式如下:
pip command modulename
参数说明:
- command:表示命令,常用的值是install(安装第三方模块),uninstall(卸载已经安装第三方模块),list(用于查看已经安装了哪些第三方模块)
- modulename:模块名,表示要安装或者卸载的模块
说明:在大型程序时需要导入很多模块,建议先导入标准模块,在导入第三方模块,最后导入自定义模块
五、安装自己写的模块到系统中
首先看一个例子,创建一个文件夹mymodules,在其中创建一个vsearch.py,内容如下:

现在进入到mymodules中,然后进入python3的终端界面,导入模块vsearch,然后调用函数,如图:

从结果看,一切输入都很正常,能正常调用并输出结果,接下来我们退出mymodules目录再次导入模块,如图:

从上图看出,导入模块失败,因为在当前目录下、site-packages、标准库中都没有此模块,此模块是在mymodules中,因此导入才会失败,如果想在任意目录中都能导入成功,需要将模块安装到site-packages中,标准库中的模块又Python核心开发人员管理,这些模块不能修改删除,也不能向标准库中添加自己的模块,但是可以向site-packages中添加自己的模块
使用标准库中的setuptools可以将模块安装到site-packages中,步骤如下:
- 创建发布描述:明确setuptools安装的模块
- 生成发布文件:文件中包括模块的代码
- 安装发布文件:将发布文件安装到site-packages中
按照上面的三个步骤,最后能为模块创建一个发布包,此包为压缩文件,其中包含site-packages安装模块所需要的全部内容
1、创建发布描述
需要创建两个文件,并且这两个文件与vsearch.py位于统一文件夹中,第一个文件名为setup.py,用来详细描述模块,此文件包含两行代码,第一行是从setuptools中导入setup()函数,第二行是调用setup()函数,如图:

- py_modules:这个发布包中的.py文件列表,本例子中只有vsearch.py
第二个文件就是readme文件,此文件中可以写包的详细描述,这个文件必须要有,但是内容却是可选的,不写为空也可以,接下来创建README.txt文件,创建后的当前目录如图:

2、创建发布文件
在windows操作系统上执行如下命令:
C:\Users\Administrator\mymodules>py -3 setup.py sdist #sdist是语法一部分,不能乱写
在linux操作系统上执行如下命令:
[root@vm-12-12-centos mymodules]# python3 setup.py sdist

执行后在当前目录下会生成一个dist文件夹,如图:

进入dist目录下,可以看到创建的压缩文件(win平台就是zip包),如图:

3、使用pip来安装发布包
在windows系统中,执行如下命令:
py -3 -m pip install vsearch-1.0.zip
在linux操作系统中,执行如下命令:
#使用python3 -m可以避免系统中有多个Python版本导致的解释器不准确
python3 -m pip install vsearch-1.0.tar.gz

安装完成后,在任意目录下都可以导入模块成功,如图:

注意:如果后续要安装或者更新代码,按照上面这三个步骤执行即可,如果是更新,记得修改setup.py中的版本号


