前言:
整理使用到的Python模块,后续有接触到新的模块也会持续更新~
1.什么是模块?
一系列功能的集合体,文件后缀名是.py
1.1. 模块导入和调用
- 文件B首次导入模块A,流程如下:
- 创建模块A的名称空间
- 执行模块A的python文件,将执行过程中产生的名字放到名称空间中
- 在文件B的名称空间中创建一个名字指向模块A的名称空间
- 当打开文件B,当加载到导入模块代码行时
- 如果导入的是整个模块,则会产生一个名称指向该模块的模块内存空间
- 如果导入的是模块内的具体工具,则会产生具体工具名称指向模块内存空间里面对应的具体工具
- 这个内存地址空间里面存的是模块A的变量,函数名等等
- 当打开文件B,当加载到导入模块代码行时
- 方法一(推荐):
- 导入: from 模块名 import 具体的工具1 [as 别名] 指向的是模块里面具体的工具的名称内存空间
- 具体工具比如函数,类,全局变量等
- 调用: 直接使用导入的工具
-
比如导入jsonpath from jsonpath import jsonpath r = {"store": { "color": "red", "price": 19.95 } } 可直接调用jsonpath j = jsonpath(r, "$..price") print(j)
-
- 导入: from 模块名 import 具体的工具1 [as 别名] 指向的是模块里面具体的工具的名称内存空间
- 方法二(不推荐):
- 导入:from 包 import *
- 如果不使用__all__属性限制,代表导入包里面所有的属性,方法,类,模块
- 使用__all__,则导入的是__all__内指定的属性、方法、类可被导入
- 导入:from 包 import *
- 方法三:
- 导入: import 模块名 [as 别名] 指向的是模块的名称空间
- 调用: 模块名(/别名).工具名
#比如导入jsonpath
import jsonpath
r = {"store":
{
"color": "red",
"price": 19.95
}
}
#调用需要: jsonpath.jsonpath
j = jsonpath.jsonpath(r, "$..price")
print(j)
循环导入问题(尽量规避):
分析: 在main.py文件里面导入a.py, 并且a.py里面导入b.py
- 在main.py执行到代码: import a 会创建a.py的名称空间并且会执行a.py
- a.py执行到代码: from b import y,会创建b的名称空间找y并且会执行b.py
- b.py执行到代码: from a import x,因为main.py已经创建了a.py的名称空间,故不会重复创建,而是直接去a.py的名称空间找x。但是在a.py里面的x是在导入b.py之后创建的,故 会报错未定义
1.2 模块文件编写顺序规范
- 文档注释描述模块功能
- 导入模块
- 导入顺序写法优先级: 内置模块 > 第三方模块 > 自定义模块文件
- 定义变量。尽量只定义局部变量,保证功能独立
- 定义类
- 定义函数
- 主程序即if __name__ == '__main__'
1.3模块导入后的查找顺序(解释器的查找顺序)
- 1.优先从内存里面找
- 2. 后从硬盘里面找
- 第1次导入的模块,就是从硬盘里面找
- 从sys.path中列出的模块的查找路径
2.模块分类:
1. 标准库
- os
- sys
- json
- random
- string
- unittest
- selenium
- datetime
- logging
- re
2. 第三方库
- 1.如何安装?
- 不是python自带的库,需要使用如下命令2选1:
- pip3 install 第三方库名 -i 镜像源 前提:pip已正确配置路径
- 临时镜像源
- 永久有效设置,在终端输入:pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
- python3 -m pip install 第三方库名 适用:确保不同环境中正确使用模块
- pip3 install 第三方库名 -i 镜像源 前提:pip已正确配置路径
- 批量安装第三方库/插件,可以使用命令:pip3 install -r 存放第三方库名文件名.txt
- 需要注意的是txt里面的第三方库,每个库占一行
- 不是python自带的库,需要使用如下命令2选1:
- 2.校验是否安装成功
- 在终端输入: 库名 --version,如果出现版本号则代表安装成功
- 3.有哪些?
- Requests
- Jsonpath
- Redis
- Pymysql
- Xlrd
3.自定义py文件
- 项目下创建的py文件,文件名要全部小写
- 文件内的类,函数,变量
3.模块的内置属性
-
__name__
- 如果是在当前文件,则__name__等于__main__
- if __name__ == "__main__"用于调试模块的代码使用
-
场景一: def func(): print("Hello") if __name__ == "__main__": func() # Hello 场景二: def decora(func): def wrapper(*args): print(f"这个函数是{func.__name__},值是{func(*args)}") return wrapper @decora def adder(x,y): return x+y if __name__ =="__main__": adder(2,3) # 这个函数是adder,值是5
- 如果是被导入,则__name__等于模块名
-
from Mona import O print(O.__name__) # Mona.O
-
- 如果是在当前文件,则__name__等于__main__
-
__file__
- 模块的绝对路径
-
1.求当前模块的绝对路径 print(__file__) # /Users/hdm/Desktop/实战练习/Mona/O.py 2.被导入,求导入的文件路径 from Mona import O print(O.__file__) # /Users/hdm/Desktop/实战练习/Mona/O.py
-
- 模块的绝对路径
-------------------------------------------------------------------
4.什么是包?
一个包含多个模块的特殊目录且目录下有__init__.py文件,一个特殊的模块
4.1 包的导入
流程跟导入模块一样,注意:因为包是文件夹,所以导入包本质是执行下面的__init__.py
- from 包名 import 子包/子模块,查找顺序是先执行包下的__init__.py查找是否有该子包/子模块->没有则从该包下的子模块。 不会导入包
- import 包名.子包,查找顺序是先执行包下的__init__.py查找是否有该子包/子模块->没有则从该包下的子模块。 会导入包
4.2 __init__.py里面的导入方式
-
绝对导入即以顶级包为起始目录
- 格式: from 包名.包下的某个py文件名 import 具体对象 / from 包名 import 子模块
- 为什么是包名.某个py文件名?
- 根据模块的查找顺序先是从内存查找,没有则是从硬盘中的sys.path中查找,而sys.path中第一个值是执行文件即导入包的文件所在的目录;被导入的模块的路径都是参照的执行文件所在的目录,要想找到包下某个py文件就必须先找到包所在路径故是包名.包下的某个py文件名
- 为什么是包名.某个py文件名?
- 前提:被导入的包所在的目录需要和执行文件所在的目录是同级或者加在sys.path中
- 格式: from 包名.包下的某个py文件名 import 具体对象 / from 包名 import 子模块
-
相对导入
- 其中.代表当前文件夹;..代表是上一层文件夹
- 格式: from .[/..]包下的py文件 import 具体功能
- 注意: 不可超出当前执行文件的顶级包
- 与绝对导入相比的好处:文件夹或者父级文件夹名称改变不需要联动修改
-
4.3目录规范
- run.py 放置在根目录下
- 因为sys.path第一个值是执行文件的目录,则run.py的目录就是根目录,就不需要额外操作将根目录加入到环境变量里面去
- conf
- 用户自定义配置文件
- lib
- 放置常用模块,包等
- core
- 放置核心功能文件
- log
- 存放日志文件
- db
- 存放对数据库相关操作的功能
- api
- requirements.txt
- 存放的是软件依赖,比如第三方模块以及版本
- readme.md
- 存放的是对项目的功能介绍,访问项目的地址
- run.py 放置在根目录下
2.1 __init__.py文件的作用:
- 判断是package的标识,不可删除用来组织包
- 命名空间初始化
- 在导入子模块前想要做一些初始化操作,可以在__init__.py里面写
- 为其他模块定义命名空间(为了防止重名)
-
在包Mona的__init__.py文件下,为模块Na定义命名空间 import Mona.Na as N __all__ = ['M','O','N'] 包Mona下有三个py文件M.py, o.py,Na.py xx.py文件: from Mona import * M.hello() O.hello() N.hello()
-
- 设置__all__通配符导入目标
-
---------未在__init__.py文件中设置__all__----------------- from Mona import * print(M.hello()) # NameError: name 'M' is not defined print(O.hello()) ---------在__init__.py文件中设置__all__----------------- 在包Mona的__init__.py文件: __all__ = ['M','O'] xx.py文件: from Mona import * print(M.hello()) print(O.hello())
-
2.2.包的作用?
方便组织和管理代码