Python 模块
1. 模块的介绍与使用
2. __main__
3. __all__ 变量
4. 包(Package)
5. import 的路径搜索
6. 重新导入模块
7. 循环导入
1. 模块的介绍与使用
在C语言中如果要引用sqrt函数,必须用语句#include <math.h>引入math.h这个头文件,否则是无法正常进行调用的。
那么在Python中,如果要引用一些其他的函数,该怎么处理呢?
在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。
说的通俗点:模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块。
import
在Python中用关键字 import 来引入某个模块,比如要引用模块 math,就可以在文件最开始的地方用 import math 来引入。
当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。
import 模块名1, 模块名2...
若要调用math模块中的函数,则必须这样引用:
模块名.函数名
问:为什么必须加上模块名调用呢?
因为可能存在这样一种情况,在多个模块中含有相同名称的函数,此时如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数。所以如果像上述这样引入模块的时候,调用函数必须加上模块名。
1 import math 2 3 # 这样会报错 4 print sqrt(2) 5 6 # 这样才能正确调用 7 print math.sqrt(2)
from…import
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。
有时候我们只需要用到模块中的某个函数,只需要引入该函数即可,此时可以用下面方法实现:
from 模块名 import 函数名1, 函数名2, ....
不仅可以引入函数,还可以引入一些全局变量、类等。
注意:
- 如果想一次性引入math中所有的东西,还可以通过 from math import * 来实现。这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
- 通过这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名,因此当两个模块中含有相同名称函数的时候,后面一次引入会覆盖前一次引入。也就是说假如模块A中有函数 function(),在模块B中也有函数 function(),如果引入A中的 function 在先、B中的 function 在后,那么当调用 function 函数的时候,是去执行模块B中的 function 函数。
as:给模块起别名
1 import time as tt 2 3 tt.sleep(1)
定位模块
当你导入一个模块,Python解析器对模块位置的搜索顺序是:
- 当前目录;
- 如果不在当前目录,Python 则搜索在系统设置的 PYTHONPATH 下的每个目录;
- 如果都找不到,Python 会查看默认路径。UNIX 下默认路径一般为 /usr/local/lib/python/;Windows 则在 Python 安装目录的 site-package 目录下;
模块搜索路径存储在 system 模块的 sys.path 变量中。变量里包含当前目录、PYTHONPATH 和由安装过程决定的默认目录。
示例:增加临时搜索路径
1 import sys 2 sys.path.append("D:\\") # 临时增加的搜索路径,程序结束后该路径也就从搜索路径中消失 3 print(sys.path)
2. __main__
作用:
- 可以根据 __name__ 变量的结果判断出,是在当前 python 模块直接执行的,还是被引入执行的,从而能够有选择性的执行测试代码。
- 如果是在本模块中直接执行程序,则 __name__ 变量的值为 “__main__”。
1 def add(a, b): 2 return a + b 3 4 5 # 进行自测 6 # 只有在当前模块下执行程序,才会执行以下代码 7 # 若本模块被其他模块引入,以下代码无法被使用 8 if __name__ == "__main__": 9 print(add(2, 3))
3. __all__ 变量
如果一个文件中有 __all__ 变量,那么也就意味着这个变量中所没有的元素,不会被 from xxx import * 时导入。
示例:
python main.py 执行结果:
Test类中的test方法 test1函数 Traceback (most recent call last): File "main.py", line 7, in <module> test2() NameError: name 'test2' is not defined
4. 包(Package)
什么是 Python 中的包?
- 将有联系的模块组织在一起,即放到同一个文件夹下,并且在这个文件夹创建一个名字为__init__.py 文件,那么这个文件夹就称之为包。
- 有效避免模块名称冲突问题,让应用的组织结构更加清晰。
示例:使用 from 包名 import 模块 的方式导入
from 包名 import 模块名 from 包名.子包名 import 模块名 from 包名.子包名.子子包名 import 模块名
__init__.py
- __init__.py 控制着包的导入行为,当此文件为空时,仅仅是把这个包导入,不会导入包中的模块。
- 在 __init__.py 文件中,定义一个 __all__ 变量,它控制着 from 包名 import * 时导入的模块。
示例:在 __init__.py 文件中写入
__all__ = ["模块名1", "模块名2"]
5. import 的路径搜索
1 >>> import sys 2 >>> sys.path 3 ['', 'C:\\Python3\\python38.zip', 'C:\\Python3\\DLLs', 'C:\\Python3\\lib', 'C:\\Python3', 'C:\\Python3\\lib\\site-packages', 'C:\\Python3\\lib\\site-packages\\utx-0.0.7-py3.8.egg']
路径搜索
- 从上面列出的目录里依次查找要导入的模块文件
- ' ' 表示当前路径
1 # 程序执行时导入模块路径 2 sys.path.append('/home/itcast/xxx') # 添加搜索路径 3 sys.path.insert(0, '/home/itcast/xxx') # 将该路径的搜索顺序放第一位
6. 重新导入模块
当某模块被导入后,若该模块进行了修改后需要重新导入使用,则需要使用 reload(模块名)。
- Python2 中可以直接使用 reload(module) 重载模块。
- Pyhton3 中则需要先导入 reload 模块:
1 >>> import math 2 >>> from imp import reload 3 >>> reload(math) 4 <module 'math' (built-in)>
7. 循环导入
a.py
from b import b
b.py
from a import a
执行结果:
1 E:\python_pra>python a.py 2 Traceback (most recent call last): 3 File "a.py", line 1, in <module> 4 from b import b 5 File "E:\python_pra\b.py", line 1, in <module> 6 from a import a 7 File "E:\python_pra\a.py", line 1, in <module> 8 from b import b 9 ImportError: cannot import name 'b' from partially initialized module 'b' (most likely due to a circular import) (E:\python_pra\b.py)
怎样避免循环导入:
- 程序设计上分层,降低耦合。
- 导入语句放在后面需要导入时再导入,例如放在函数体内导入。