目录
一、模块
在Python中,一个以.py为后缀名的文件就是一个模块。模块可以被其他模块调用,当你写了一个公共函数,需要在其他文件中调用,就可以将这个函数放在一个单独的文件中(这个文件就是模块),然后在其他文件中导入,就可以像在本文件中调用函数一样调用这个模块中的函数了。模块一般分为系统内置模块(直接导入)、自定义模块(导入时需注意路径问题)和第三方开源模块(可通过pip install安装,安装后可直接导入)。
二、什么是包?
包是对模块的管理,通常是一个目录。一个包里可以有很多模块,可以分不同层级的包。通常一个目录下需包含一个__init__.py文件才能成为一个包被其他模块引用,__init__.py文件可以为空,一般用来初始化工作或设置__all__值。
三、导入方式
1、import
import packageA.subPackageA1.(...).subPackageAn.moduleA,使用时,必须用全路径名。
2、from...import
from packageA.subPackageA1.(...).subPackageAn import moduleA
from packageA.subPackageA1.(...).subPackageAn.moduleA import functionA
四、导入路径
moduleA1.py文件中内容:
1、被导入的模块和使用的模块属于同一个目录
import实现:
from...import实现:
运行结果:
2、被导入的模块和使用模块不是不是同一个目录(非子级目录)
在packageB所在目录中运行结果:
从上发现,程序报错:ModuleNotFoundError: No module named 'packageA' 没有找到名叫packageA的模块。这是为什么呢?
这就需要从import的路径说起了,在Python中,import搜索模块的路径按照以下策略:
(1)首先在当前目录下查找模块;
(2)若当前目录下找不到,则在PYTHONPATH环境变量列表路径中一次搜索;
(3)若步骤2中仍搜索不到,则在Python安装路径中寻找。
以上搜索路径都被包含在sys模块中的path变量中,即Python中搜索模块的路由是包含在path变量中,我们可以查看:
由上可知,path的值为['', 'C:\\Program Files\\Python36\\python36.zip', 'C:\\Program Files\\Python36\\DLLs', 'C:\\Program Files\\Python36\\lib', 'C:\\Program Files\\Python36', 'C:\\Users\\EDZ\\AppData\\Roaming\\Python\\Python36\\site-packages', 'C:\\Program Files\\Python36\\lib\\site-packages', 'C:\\Program Files\\Python36\\lib\\site-packages\\django-3.0.5-py3.6.egg', 'C:\\Program Files\\Python36\\lib\\site-packages\\asgiref-3.2.7-py3.6.egg', 'C:\\Program Files\\Python36\\lib\\site-packages\\sqlparse-0.3.1-py3.6.egg'],是一个路径列表,其中第一个‘’代表当前路径。在Windows中,我们可以通过chdir查看当前路径:
当前路径是C:\Users\EDZ\Desktop\PyBase\packageB,在此路径中,找不到packageA模块,接着去列表后面元素所代表的路径中查找该模块也无法找到,则会报出找不到packageA的错误。
那有什么解决的办法呢?
既然搜索路径是在保存path变量中的,那么将packageA的路径也加入到这个列表变量中,packageA就能被找到了。我们知道一个文件的路径包含绝对路径和相对路径两种,那么添加到path变量中也分绝对路径和相对路径。
1)绝对路径的实现:
修改代码如下:
import实现:
from...import实现:
在packageB所在目录中运行结果(import和from...import实现方式结果一致):
2)相对路径实现方式(相对路径的表示:“.”表示当前路径,“..”或“../”表示相对当前路径的上一级路径)
修改代码如下:
import实现:
from...import实现:
在packageB所在目录中运行结果(import和from...import实现方式结果一致):
3、子级目录导入
新增目录文件
1)上级目录模块导入子级目录模块
import实现:
from...import实现:
在packageA.py文件所在目录下运行结果(import和from...import实现方式结果一致):
2) 子级目录模块导入上级目录(需要将路径包含到系统环境变量path中,导入绝对路径方式在此不再赘述,推荐使用相对路径导入方式,以便代码在不同操作系统上移植)
import实现:
from...import实现:
此时moduleA1.py文件应为:
在subModuleA2.py文件所在目录下运行结果(import和from...import实现方式结果一致):
在上述 from...import实现时,若moduleA1.py为:(subModuleA2.py文件不变)
此时运行报错:
原因是:两个文件相互import时,会产生循环导入。两者陷入了死循环。解决办法:像上面采用的方式一样,注释掉moduleA1.py中对subModuleA2的调用;若实在要在moduleA1.py调用subModuleA2模块,可以使用如下方法:
此时运行结果正常:
4、使用__init__.py文件中的__all__方法后的导入
前提:目录及文件结构如下:
若要在moduleB2.py文件中调用moduleA1模块:
step1:修改packageB目录下__init__.py文件为:
step2:moduleB2.py文件为:
step3:在packageB目录下运行文件moduleB2.py结果为:
总结:在使用import时,一定要注意文件导入路径,否则在运行时,很容易出现import错误。__init__.py中引进包的缺点是看不出哪个模块的真实路径,优点是导入路径减少,书写相对简单。
五、常用标准模块
1、sys模块
sys模块:这个模块提供了一些与解释器交互的函数或由解释器维护/使用的对象。
常见的有:
1)sys.path 模块的查找路径, path[0]是脚本目录。
2)sys.argv python命令的参数,是一个列表。一般来说,argv [0]是脚本路径。
2、os模块
os模块:包含了通过NT or Posix应用编程接口对我们所在系统的常规操作。
常见的有:
1)cmd_res = os.system("dir") #执行命令 不保存结果 若执行成功cmd_res=0
2)cmd_res = os.popen("dir").read() #执行命令 保存结果 若执行成功cmd_res为dir命令运行结果
3)os.mkdir("new_dir")在当前路径下创建一个目录