在python中一个.py文件就是一个模块,使用模块既可以保证代码的重用性,又能增强程序的结构性和可维护性。对于内置模块和第三方模块提供的现成功能的拿来主义能极大的提高程序员的开发效率。
首次导入模块做三件事:
1、执行源文件代码
2、产生一个新的命名空间用于存放源代码执行过程中产生的名字
3、在当前执行文件的名称空间生成一个名字指向新创建的模块命名空间,引用模块命名空间中的名字要加上模块名前缀。
第一次导入模块将其加载到内存空间,之后的重复导入就会直接从内存中加载已存在的模块,不会重复执行导入,通过sys.modules可以查看内存中已加载的模块名。
模块名应该遵循小写形式。
模块按分类导入:内置模块,第三方模块,自定义模块,虽然能通过逗号分隔不同的模块,但建议每行只导入一个模块,这种行为更加规范,可读性更强。
我们也可以在函数中导入模块,对比在文件头部导入模块术语全局作用域,在函数内导入模块则属于局部作用域。
模块内变量的导入不加前缀的好处是能使我们的代码更简洁,但是也会容易和当前名称空间内的名字发生冲突,如果当前名称空间存在相同的名字,后定义的名字会覆盖之前定义的名字。
只能在模块最顶层使用 from module import *这种导入方式,在函数内是非法的.这种方式很容易产生名称冲突。模块中可以定义__all__这个列表变量来存储要导出的变量名(from module import * 会自动导入__all__中定义的名字。不在all中的名字对外没有导出看不到的。)
循环导入问题指的是在一个模块加载/导入的过程中导入另外一个模块,而在另外一个模块中又返回来导入第一个模块中的名字,由于第一个模块尚未加载完毕,所以引用失败、抛出异常,究其根源就是在python中,同一个模块只会在第一次导入时执行其内部代码,再次导入该模块时,即便是该模块尚未完全加载完毕也不会去重复执行内部代码
模块的四个通用级别:
1、使用纯python代码写的.py文件
2、包含一系列模块额包
3、使用C编写的链接到python解释器上的内置模块。
4、使用C或C++编译的扩展模块。
导入一个模块时,如果模块已加载在内存中,则直接引用,否则会优先查找内置模块,然后按从左到右的顺序依次检索sys.path中定义的路径,知道找到模块对应的文件为止,否则抛出异常。
sys.path第一个路径通常为空,代表执行文件所在的目录,所以被导入模块与执行文件在同一目录下肯定是可以正常导入的。而针对被导入模块和执行文件不在同一目录的情况,为了确保模块对应的文件能被找到,文件所在的路径目录需要被添加到sys.path中。
包是一个包含__init__.py文件的文件夹,文件夹内可以组织子模块或子包。
注意:在python3中,即使包中没有__init__.py文件,import导入也不会报错,在python2中,包中必须包含该文件,否则就会报错。包的存在是为了导入使用而不是直接运行,包是模块的一种形式而已,包本质就是一种模块。
包属于模块的一种,包以及包内的模块均是用来被导入使用的,而绝非被直接执行,首次导入包会做三件事:
1、执行包下的__init__.py文件
2、产生一个新的名称空间用于存放__init__.py执行过程中产生的名字。
3、在当前执行文件所在的名称空间得到一个指向__init__.py名称空间的名字。导入包时并不会导入包下所有的子模块与子包。
包的导入语句分import和from ... import.. 在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包。
import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件。
针对包内模块间的相互导入推荐使用相对导入。相对导入只能在包内使用,用相对导入不同目录下的模块是非法的。无论Import还是from-import 凡是在导入时带点的,点的左边必须是包,否则会语法错误。
网友评论