Python-模块

  1. 模块
    1. 为什么使用模块
    2. 1、导入整个模块,语法格式:
    3. 2、导入模块中的属性

模块

模块就是python中的一个.py文件
可以在模块中定义变量、函数和类,定义在模块中的变量、函数和类统称为模块的属性。

为什么使用模块

1、代码重用
在一个模块中可以导入另一个模块,从而重用另一个模块中定义的属性。
2、避免属性名冲突
不同的模块中可以存在相同名称的属性。

为了更好的组织和管理模块,python引入了包。

在某个目录下添加模块__init__.py后,这个目录就变成了包、因此包是包含了特定模块的特殊目录。
模块__init__.py的作用是初始化其所在的包,如果不需要初始化,其内容可以为空。
目录支持嵌套,所以包也支持嵌套,包中还可以有子包

python官方提供了标准库,其中有非常多的模块可供我们使用,用以完成不同的任务

如果想要使用标准库中的模块,必须使用import语句进行导入,导入方式有两种:

1、导入整个模块,语法格式:

import  [包名.]模块名

如果被导入的模块在一个包结构中,那么必须要通过其所有的父包导航到该模块:

顶层父包名.子包名.....子包名。

导入整个模块后,就可以访问模块中的属性了(包括:变量、函数和类)。其语法格式为:

[包名.]模块名.属性名

导入整个模块时,可以给导入的模块起一个别名,

import [包名.]模块名 as 模块的别名

2、导入模块中的属性

导入模块中某个属性的语法格式为:

from [包名.]模块名 import 属性名

同样,如果被导入的模块在一个包结构中,那么必须要通过其所有的父包导航到该模块:

顶层父包名.子包名.....子包名。

导入模块中的属性后,就可以直接访问模块中的属性了,而无需添加前缀“[包名.]模块名”,从而使得代码更加简洁,但是与添加前缀相比,代码的可读性差一点

导入模块中多个属性

from [包名.]模块名 import 属性名1, 属性名2, ..., 属性名n

导入模块的属性时,可以给导入的属性起一个别名

from [包名.]模块名 import 属性名1 as 属性名1的别名,  属性名2 as 属性名2的别名,  ...,  属性名n as 属性名n的别名

可以将模块中的属性一次性全部导入,其语法格式为:

from [包名.]模块名 import *

强烈不推荐这种导入方式,因为:
1、效率低(将所有的属性全部导入了)
2、代码的可读性低(不知道具体导入了哪些属性)
3、容易出错(当两个模块中存在相同的属性)

当导入整个模块时,如果模块在一个包结构中,也可以适用类似导入模块中属性的语法格式:

from 包名 import 模块名

使用第三方库中的模块
除了官方提供的标准库之外,还有很多第三方库可供使用,以完成不同的任务
如果想要使用第三方库中的模块,必须先使用工具pip下载安装第三方库,然后通过import语句进行导入

PyPI(Python Package Index)
是Python官方的,基于web的,几种管理的,第三方软件仓库,所有人都可以从PyPI下载安装第三方库,或者将自己开发的库发布到PyPI
网址:https://pypi.org/

pip(Package Install for Python)

第三方库的安装路径

[root@lyucan site-packages]# pwd
/usr/local/python3/lib/python3.7/site-packages         # /usr/local/python3是安装路径
[root@lyucan site-packages]# ll
total 36
drwxr-xr-x. 19 root root 4096 Jul 24 11:21 django
drwxr-xr-x.  2 root root 4096 Jul 24 11:21 Django-2.0.7.dist-info
-rw-r--r--.  1 root root  126 Jul  8 00:26 easy_install.py
drwxr-xr-x.  5 root root   90 Jul 24 11:20 pip
drwxr-xr-x.  2 root root 4096 Jul 24 11:20 pip-18.0.dist-info
drwxr-xr-x.  5 root root   89 Jul  8 00:26 pkg_resources
drwxr-xr-x.  2 root root   40 Jul  8 00:26 __pycache__
drwxr-xr-x.  4 root root 4096 Jul 24 11:20 pytz
drwxr-xr-x.  2 root root 4096 Jul 24 11:20 pytz-2018.5.dist-info
-rw-r--r--.  1 root root  119 Jul  8 00:25 README.txt
drwxr-xr-x.  6 root root 4096 Jul  8 00:26 setuptools
drwxr-xr-x.  2 root root 4096 Jul  8 00:26 setuptools-39.0.1.dist-info

pip3相关命令

1、查看帮助信息
pip3

2、列出已经安装的所有三方库
pip3 list

3、模糊搜索某个第三方库
pip3 search xxx

4、安装指定的第三方库(及其版本号)
pip3 install xxx
pip3 install xxx==y.y

5、升级指定第三方库
pip3 install --upgrade xxx

6、卸载指定的第三方库(及其版本号)
pip3 uninstall xxx
pip3 uninstall xxx==y.y

7、查看pip3之后某个命令的帮助信息
pip3 <cmd> --help

使用当前项目中的模块
如果想要使用当前项目中的模块,必须通过import语句进行导入,有三种导入方式:
1、直接导入
直接导入当前目录中的模块名
2、绝对导入
导入模块名的绝对路径
3、相对导入
导入模块名的相对路径,一个“.”表示当前目录,两个“..”表示当前目录的父目录
当直接运行某个模块时,该模块就变成了主模块,主模块位于最顶层,与同目录下的其他模块无法构成相对关系,因此,当直接运行某个模块时,该模块不能使用相对导入。

import语句的执行流程
例如

import sys

当使用import语句导入模块时,解释器会根据sys模块的modules属性值来查找模块是否已经被导入了。
1、如果模块已经被导入了,解释器什么都不做。
2、如果模块没有被导入
解释器按照某种路径搜索模块;
(可选)将搜索到的模块编译为pyc字节码文件;
执行编译生成的字节码文件从而运行模块;

解释器搜索模块路径
解释器搜索模块路径存放在sys的变量path中

>>> import sys
>>> sys.path
['', '/usr/local/python3/lib/python37.zip', '/usr/local/python3/lib/python3.7', '/usr/local/python3/lib/python3.7/lib-dynload', '/root/.local/lib/python3.7/site-packages', '/usr/local/python3/lib/python3.7/site-packages']

顺序为:当前目录、标准库目录、第三方库安装目录

在代码运行过程中可以改变这个值来改变模块搜索路径,但是在代码运行完成后,这个值就会还原

为了永久的修改这个值,可以设置PYTHONPATH环境变量,PYTHONPATH对应的路径会自动添加到sys.path中。修改后的搜索路径在代码运行后仍然有效。

当使用import语句导入模块时,如果模块还没有被导入,首先,解释器会按照某种路径搜索模块,其次,搜索到的模块可能会被编译为pyc字节码文件。
到搜索到的模块被第一次导入时,他会被便以为pyc字节码文件。pyc字节码问价内存放在与该模块同目录下的目录__pycache__中,其命名格式为:模块名.cpython-版本号.pyc。这样,模块的字节码问价就被缓存起来了,再次加载该模块时,如果改模块没有发生变化,则无需将搜索到的模块编译为pyc字节码文件,而是直接读取缓存中的pyc字节码文件,从而提高加载速度。

导入包中的模块时,会先导入包中的__init__.py,因此,在运行被导入的模块之前,会从最顶层的父包开始,先依次运行所有父包中的__init__.py

模块内的数据访问控制

1、使用模块特殊属性__all__

为了在某种程度上实现模块内的数据访问控制,还可以在模块被定义特殊属性__all__。这样。使用语句from 模块名 import *只能导入特殊属性__all__中定义的属性,但是,使用“import 模块名”语句仍然可以导入所有的属性。

2、为了在某种程度上实现模块内的数据访问控制,可以在模块内的某些属性前添加单下划线_,这样,就无法使用语句from 模块名 import *导入相应的属性了,但是,使用语句import 模块名仍然可以导入相应的属性。

3024b2df-788d-4d4a-9923-fd4bf1114d57-image.png

当使用语句from 模块名 import *导入属性时:
如果在模块内的某个属性前添加了单下划线_,又将这个属性定义在模块内的特殊属性__all__中,那么__all__比单下划线具有更高的优先级。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com