8 复杂程序组织
为了维护项目代码的管理、
模块:不同的代码文件就是不同的模块,简单的说就是每个.py文件都是一个模块。
包:将不同功能的代码放入不同的文件夹中,他们可以互相引用,这就是包。
8.1 模块
8.1.1 模块概述
三种方法:
import 模块名
import 模块名 as 新名字 #可以防止名称重复或者书写代码简便
from 模块名 import 函数名 #只是导入了某一个函数或名字,不是整个模块
In [10]:
import math
from math import sqrt
import math as shuxue
print('调用math.sqrt:\t',math.sqrt(2))
print('直接调用sqrt:\t',sqrt(2))
print('调用shuxue.sqrt:\t',shuxue.sqrt(2))
调用math.sqrt: 1.4142135623730951 直接调用sqrt: 1.4142135623730951 调用shuxue.sqrt: 1.4142135623730951
8.1.2 自己编写模块
自己编写模块其实和平常写Python程序是相同的,他既可以是一个解决某个问题的独立程序,也可以是几个函数构成。
模块的名称就是代码保存的文件名。
8.1.3 模块位置
编写好的模块只有被python找到才能被导入。
同一目录下可以不用设置
不同目录就需要查找模块路径
import sys #导入sys模块
sys.path.append('D:\\TEST\module') #添加查找路径,必须使用绝对路径
import module_test #需要导入的路径为D:\\TEST\module下的模块
8.1.4 pycache目录
这个目录用于存放字节码文件,对于模块,Python总是在第一次调用后将其编译成字节码的形式,来提高程序的启动速度。
被编译的程序也是可以运行的。
如果不想将源文件发布,可以发布编译后的程序。py_compile模块编译。
import py_compile
py_compile.compile('xxx.py','xxx.pyc')
8.1.5 具有独立运行能力的模块
每个Python程序在运行时都有一个__name__属性。在程序中通过对__name__属性值的判断,可以让程序在作为导入模块和独立运行时都可以正确运行。
如果程序作为模块被导入,__name__属性被设置为模块名。
如果程序独立运行,__name__属性被设置为"__main__"。
下面的代码既可以独立运行,又可以作为模块被其他程序导入使用。(可以通过该方式来测试模块的错误)
In [18]:
print('导入的测试模块输出!')
name = 'module_test'
def m_t_pr():
print('模块module_test中m_t_pr()函数')
m_t_pr()
print(name)
''' 下面的语句其实可用可不用,待以后学习后补正
if __name__ == '__main__':
m_t_pr()
print(name)
'''
导入的测试模块输出! 模块module_test中m_t_pr()函数 module_test
Out[18]:
" \nif __name__ == '__main__':\n m_t_pr()\n print(name)\n"
8.2 包
8.2.1 包概述
当项目有较多功能模块时,可以使用包来管理。避免名字冲突及维护管理。
包其实就是一个文件夹,但其中必须包含一个名为"__init__.py"的文件,可以是一个空文件。
包也可以嵌套,既把子包放入包中。按目录顺序以点号分割使用import导入。
三种方法导入,调用方式也不同: #a是包,index是python文件,do()是index中的方法
import a.index #导入后需使用a.index.do()调用
form a import index #导入后需使用index.do()调用
from a.index import hdl #导入后使用do()调用
8.2.3 包详解
如果导入只用了目录,则会直接执行"__init__.py"
import a 等于调用了a目录下的__init__.py
根目录 1级目录 二级目录
M a
1
2
b
3
4
c
5
同级目录下调用:如果1要用2
import 2
不同目录调用:如果1要调用3
from M.b import 4
调用子包:如果a要调用2
from .a imort 2
总结,同级目录直接调用,不同目录必须从父目录,子包相对导入。