14. 模块与导入模块
2021/11/5 23:16:21
本文主要是介绍14. 模块与导入模块,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
模块
模块介绍
就是一系功能的集合体,分为三大类,一种是内置模块,一种是自定义模块(自己写的),一种是第三方模块(别人写的)
本质上一个python文件本身就是一个模块,文件名是m.py,模块名是m
模块分为四种形式:
- python写的.py文件就是一个模块
- 已经被编译为共享库或DLL的c或者c++拓展
- 把一些列模块组织到一起的文件夹
- 使用c编写并链接到Python解释器的内置模块(文件夹下面必须有一个__init__.py文件,该文件夹被称为包)
模块的优点:
- 内置与第三方模块不需要定义,直接可以使用,这种拿来主义极大的提高了开发的效率
- 自定义模块能将常用的函数(功能)提取出来放在一起,方便调用和共享,减少了代码冗余,是代码结构更加清晰
首次导入模块发生的三件事
-
执行a(假设是a.py文件)模块里面的代码
-
产生a.py文件的名称空间,将a.py代码执行过程中的产生的名称丢到名称空间中
-
在当前文件中产生一个名称a(可以理解为变量,但是不是变量a),该名称指向2中产生的名称空间
之后的导入,不会再重复上述的内容,而是直接引用首次导入产生的a.py的名称空间(模块只在第一次导入的时候执行,之后的导入不会再执行,而是直接使用)
import导入模块
- 直接导入:import xxx
### 1. 根据名称直接访问,指名道姓,这种方式不会和当前文件中的变量产生冲突(name和a.name是不一样的) # 无论是查看还是修改都是原文件上的操作,与调用位置无关 import a name='张三' print(a.name) # 取a模块的name变量,不是'张三' print(a.func) # 取a模块中的func函数 ### 2. 导入多个模块 import a import b # 上面和下面的两种方式是等价的,但是下面的方法不推荐使用,主要是不清晰 import a,b ### 3. 起别名:主要是模块名字太复杂的时候使用 import ahsjdadhajsdajdglfj as b b.get ### 4. 模块是第一类对象 ### 5. 自定义模块命名的时候应该是全小写加下划线的方式 ### 6. 函数内也可以使用模块 def func(): import a pass
-
from 文件名 import 变量/函数
import 模块名虽然解决了名称冲突的问题,但是在使用时必须加上前缀,比较麻烦,所以有了下面的方法
from a import func from a import func1 from a import func2 # 两种方式,还是推荐上面的写法 from a import func,func1,func2 ## 导入全部的内容 from a import * # 不推荐使用
这种方式有一个问题,就是当前文件和模块中的文件有相同名称的变量/函数时,Python解释器会优先调用当前文件的变量/函数
控制导入的名称(all属性)
__all__属性在被导入的模块中会显示所有模块中的名称,包含变量和函数的,形成一个列表,实际上在用*进行导入的时候,就是在该列表中进行检索,当然,可以对all属性进行设置,控制被导入的名称这样被导入的时候,只能使用列表中的名称
__all__=[a,b,func1,func2]
python文件的两种用途
- 被当做程序直接运行
- 被当作模块运行
每一个python文件都有一个属性name,能够显示文件的用途
# 1. 当文件被当做程序直接运行的时候 __name__='__main__' # 2. 当文件被当做模块运行时 __name__='文件名,也就是模块名' ### 所以可以在文件中添加判断,指定文件的用途 if __name__=='__main__': print('文件被当做程序运行') else: print('文件被当做模块运行')
循环导入问题
就是在a文件中导入b模块,在b文件中导入a模块
# 举例说明一下 # a文件 from b import b a=111 # b文件 from a import a b=222 # 过程:运行a文件,执行到from b import b,再去b文件找b,运行到from a import a,再去a文件找a,此时模块a已经开辟了名称空间了,所以直接找a变量,但是a变量还没赋值(代码还没执行到那里),报错 # 解决方案1(不推荐) # a文件 a=111 from b import b # b文件 b=222 from a import a # 解决方案2(不到万不得已不要使用) # a文件 def func1(): from b import b a=111 # b文件 def func1(): from a import a b=222 ### 这样文件加载的时候不会执行函数内的代码,只有在调用函数的时候才会导入,此时的b已经加载完成了
模块查找优先级
- 内存中(包括内置模块)(sys.modules查看已经加载到内存中的模块,考虑到性能的原因,每个模块只被导入一次,放入字典sys.module中,如果改变了模块的内容,必须重启程序,python不支持重新加载或卸载之前导入的模块)
- 硬盘中(文件夹中)是按照sys.path中的文件夹顺序进行查找
# 从硬盘中查找 import sys print(sys.path) # 结果是一个列表,第一个元素是当前文件夹的路径,第二个元素是项目的路径(pycharm安装时添加的,不重要),第三个元素是 # sys.modules查看内存中的模块:返回一个字典,里面是加载到内存中的模块
sys.path的应用
sys.path.append(r'模块路径')
当找不到模块存在的路径的时候,可以使用这种方法将文件路径添加到路径中(这是临时添加,文件关闭的时候就会取消)
编写规范的模块
#!/usr/bin/env python # 通常只在类unix环境有效,作用是可以使用脚本名来执行,而无需直接调用解释器 "The module is used to..." # 模块的文档描述 import sys # 导入模块 x=1 # 定义全局变量,如果非必须,则最好使用局部变量,这样可以提高代码的易维护性,并且可以节省内存提高性能 class Foo: # 定义类,并写好类的注释 'Class Foo is used to...' pass def test(): # 定义函数,并写好函数的注释 'Function test is used to…' pass if __name__ == '__main__': # 主程序 test() # 在被当做脚本执行时,执行此处的代码
顺序不固定,但是这样的顺序更加的清晰
这篇关于14. 模块与导入模块的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-27MQ底层原理资料详解:新手入门教程
- 2024-11-27MQ项目开发资料入门教程
- 2024-11-27RocketMQ源码资料详解:新手入门教程
- 2024-11-27本地多文件上传简易教程
- 2024-11-26消息中间件源码剖析教程
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器
- 2024-11-26Java云原生资料:新手入门教程与实战指南
- 2024-11-26JAVA云原生资料入门教程