菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
483
0

模块

原创
05/13 14:22
阅读数 58800

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解析器对模块位置的搜索顺序是:

  1. 当前目录;
  2. 如果不在当前目录,Python 则搜索在系统设置的 PYTHONPATH 下的每个目录;
  3. 如果都找不到,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)

怎样避免循环导入:

  • 程序设计上分层,降低耦合。
  • 导入语句放在后面需要导入时再导入,例如放在函数体内导入。

 

发表评论

0/200
483 点赞
0 评论
收藏