模块、包、模块的导入、跨文件导入、软件开发目录规范
一、模块
一系列功能的集合体,分为三大类:
1.内置的模块
2.第三方的模块
3.自定义的模块:一个python文件就是一个模块,文件名m.py, 模块名叫m。
模块的四种形式:
1..py文件
2. 已经被编译为共享库或者DLL的C或者C++扩展
3.把一系列模块组合到一起的文件夹(文件下有一个__init__.py文件,该文件称之为包)
4.使用C编写并连接到python解释器的内置模块
二、自定义模块的使用
1.首次导入自定义模块时会执行自定义模块所在的文件,创建相应的文件名称空间,
***应用模块时,需要操作(文件名.功能)***;
***无论是查看还会修改都是以原模块为基准,与调用位置无关***
导入模块规范
1.导入内置模块
2.导入第三方模块
3.导入自定义模块
三、python 文件的两种用途
1.当做程序导入,
2.当做模块导入,没有被引用时就被回收了
import 导入模块,使用时必须加前缀 "模块名.":
优点:肯定不会和当前名称空间的名字冲突
缺点:加前缀显得麻烦
解决办法:from 模块存放的文件名 import 模块名
优点:代码更加精简
缺点:容易与当前名称空间混淆
import导入模块发生的三件事:
1、执行源文件代码
2、产生一个新的名称空间用于存放源文件执行过程中产生的名字
3、在当前执行文件所在的名称空间中得到一个名字foo,该名字指向新创建的模块名称空间,若要引用模块名称空间中的名字,需要加上该前缀。
四、循环导入问题
指的是在一个模块加载/导入的过程中导入另外一个模块,而在另外一个模块中又返回来导入第一个模块中的名字,由于第一个模块尚未加载完毕,所以引用失败、抛出异常,究其根源就是在python中,同一个模块只会在第一次导入时执行其内部代码,再次导入该模块时,即便是该模块尚未完全加载完毕也不会去重复执行内部代码
五、模块导入的先后顺序
查看查找路径方法
import sys print(sys.path)
先从内存找,再从硬盘找。
sys.modules查看已经加载到内存中的模块
import sys print(sys.modules)
包跨文件的调用(处理好环境变量):
如果模块和当前运行文件不再同意目录下,导入模块操作方法
import sys sys.path.append(r'模块路径') import 模块
from pool.run imort 模块
把文件路径改成动态
# 把项目的根目录加入到环境变量中 import sys import os sys.path.append(r'绝对路径')
# 改成动态 __file__ # 当前文件的绝对路径 import os BASE_DIR=os.path.dirname(os.path.dirname(__file__))
__file__ # 当前文件的绝对路径 import os BASE_DIR=os.path.dirname(os.path.dirname(__file__)) sys.path.append(BASE_DIR)
# 路径拼接 import os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) LOG_PATH=r'%s/log/user.log'%BASE_DIR
模块编写规范
1.文档描述
2.导入的模块
3.定义全局变量
4.定义类,做好注释
5.定义函数,做好注释
六、包(就是模块)
就是一个含有__init__.py文件的文件夹,文件夹内可以放子模块和子包
包是模块的一种,而包以及包内的模块都是被用来导入使用的。
首次导入包做的三件事:
1、执行包下的__init__.py文件
2、产生一个新的名称空间用于存放__init__.py执行过程中产生的名字
3、在当前执行文件所在的名称空间中得到一个名字pool,该名字指向__init__.py的名称空间,例如http://pool.xxx和pool.yyy中的xxx和yyy都是来自于pool下的__init__.py,也就是说导入包时并不会导入包下所有的子模块与子包
包的导入:
绝对导入,以顶级包夹作为起始
import pool.m1 from f1
强调!!!!
1.关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
2、包A和包B下有同名模块也不会冲突,如A.a与B.a来自俩个命名空间
3、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
相对导入:.代表当前文件所在的目录,..代表上一层文件夹 【仅限于包内使用,不能跨包(包内模块之间的导入,推荐使用相对导入)】
七、软件开发的目录规范
1.可读性高
2.可维护性高
Foo/ |-- core/ | |-- core.py | |-- api/ | |-- api.py | |-- db/ | |-- db_handle.py | |-- lib/ | |-- common.py | |-- conf/ | |-- settings.py | |-- run.py |-- setup.py |-- requirements.txt |-- README
解释:
• core/: 存放业务逻辑相关代码
• api/: 存放接口文件,接口主要用于为业务逻辑提供数据操作。
• db/: 存放操作数据库相关文件,主要用于与数据库交互
• lib/: 存放程序中常用的自定义模块
• conf/: 存放配置文件
• run.py: 程序的启动文件,一般放在项目的根目录下,因为在运行时会默认将运行文件所在的文件夹作为sys.path的第一个路径,这样就省去了处理环境变量的步骤
• setup.py: 安装、部署、打包的脚本。
• requirements.txt: 存放软件依赖的外部Python包列表。
• README: 项目说明文件。
除此之外,有一些方案给出了更加多的内容,比如LICENSE.txt,ChangeLog.txt文件等,主要是在项目需要开源时才会用到,请读者自行查阅。