- 一 模块简介
- 1.1 模块的分类
- 1.2 模块的形式
- 二 导入模块的两种方式
- 2.1 import
- 2.2 from ... import ...
- 2.3 两种导入方式的优缺点
- 三 补充知识
- 3.1 起别名
- 3.2 导入多个名字
- 3.3 一次导入全部
- 四 循环导入
- 五 判断文件类型
- 六 模块的查找顺序
- 七 绝对导入和相对导入
- 7.1 绝对导入
- 7.2 相对导入
- 八 包
- 8.1 包的概念
- 8.2 包的作用
- 8.3 具体使用
模块就是一系列功能的集合体
1.1 模块的分类- 内置模块
解释器自带,可直接导入 - 自定义模块
自己编写的模块 - 第三方模块
别人编写的模块
- 一个py文件
- 一个由多个py文件组成的问价夹
- 已被编译为共享库或DLL的c或C++扩展(了解)
- 使用C编写并链接到python解释器的内置模块(了解)
自定义一个custom_module模块
# custom_module.py
name = 'jasper'
def func1():
print('from custom_module func1')
def func2():
print('from custom module func2')
def alter():
global name
name = 'jack'
在md_import文件中导入custom_module模块
# md_import.py import custom_module name = 'lili' print(name) # lili print(custom_module.name) # jasper print(custom_module.func1) #custom_module.func1() # from custom_module func1 custom_module.alter() print(custom_module.name) # jack
执行md_import文件会发生三件事情
- 产生md_import的全局名称空间,用来存放md_import文件执行过程中产生的名字
- 执行import custom_module代码,产生一个custom_module的全局名称空间,执行custom_module文件代码,将执行过程中产生的名字放到custom_module全局名称空间
- 在md_import名称空间中得到custom_module名字,该名字绑向custom_module全局名称空间,执行import下的代码
# md_import.py from custom_module import name, func1 print(name) # jasper print(func1) #2.3 两种导入方式的优缺点func1() # from custom_module func1
- import
优点:可以使用模块中的所有名字,不会产生冲突
缺点:模块中有的名字可能不会用到,浪费空间资源 - from-import
优点:不用使用模块名点调用
缺点:名字容易产生冲突(绑定关系被修改)
一个模块名太复杂或不同模块中的名字相同都可以起别名。
import custom_module as md md.func1() # from custom_module func1 from custom_module import name as name1 from custom_module1 import name as name2 print(name1) print(name2)3.2 导入多个名字
# 不推荐使用 import os, sys, json # 推荐使用 import os import sys import json # 多个名字在一个模块中 from custom_module import name, func1, func23.3 一次导入全部
如果需要用到模块中的名字较多时,可以采用from_import * 的形式来节省代码,模块中可以用__all__控制*代表什么
__all__ = ['name', 'func1']
name = 'jasper'
def func1():
print('from custom_module func1')
def func2():
print('from custom module func2')
def alter():
global name
name = 'jack'
from custom_module import * print(name) # jasper func1() # from custom_module func1 func2() # 不可用 alter() # 不可用四 循环导入
# md1.py
print('执行md1')
from md2 import y
x = 1
# md2.py
print('执行md2')
from md1 import x
y = 10
分析过程:执行md1 ——》 打印’执行md1’ ——》 导入md2 ——》 执行md2代码 ——》 打印’执行md2’ ——》 导入md1 ——》执行md1 ——》打印’执行md1’ ——》导入md2 由于md2已经导入过了,所以直接用内存中的md2拿y 而此时的y还没有被运行到 所以报错
解决办法:将y定义好 在导入md1
# md1.py
x = 1
print('执行md1')
from md2 import y
# md2.py
y = 10
print('执行md2')
from md1 import x
在程序设计中尽量不要出现循环导入
五 判断文件类型# md1.py
import md2
print(__name__) # __main__
print(md2.__name__) # md2
if __name__ == '__main__':
md2.func() # from md2 func
# md2.py
def func():
print('from md2 func')
一个python文件有两种用途,被当作脚本运行和当作模块被导入,每个py文件都有一个__name__属性,当文件被执行时,__ name__的返回值是__main__,当一个py文件被导入时,__ name__的结果是模块名。
# md2.py
def func():
print('from md2 func')
if __name__ == '__main__':
print('被执行时执行的代码')
else:
print('被当作模块导入时执行的代码')
六 模块的查找顺序
内存中查找 >>> 内置模块中查找 >>> sys.path中查找(系统文件路径)
sys.path被称为模块搜索路径,是一个列表,和环境变量有点类似。
import sys print(sys.path) ''' [ 'D:\PythonLearn\day22', 'D:\PythonLearn\day22', 'D:\PyCharm 2022.1.1\plugins\python\helpers\pycharm_display', 'D:\Python39\python39.zip', 'D:\Python39\DLLs', 'D:\Python39\lib', 'D:\Python39', 'D:\Python39\lib\site-packages', 'D:\PyCharm 2022.1.1\plugins\python\helpers\pycharm_matplotlib_backend' ] '''
如果导入不和执行文件在同一路径下的模块,就要将该模块的绝对路径添加到sys.path中。
import sys sys.path.append(r'D:PythonLearnday22aaabbbccc') print(sys.path) import test_md # 导入不同路径下的模块 test_md.func() # from test func七 绝对导入和相对导入 7.1 绝对导入
以执行文件的sys.path为起始位置,一层一层的往下找
pycham会自动将项目根目录加到sys.path中,从跟目录开始往下找一定不会出错。如果不是pycharm运行,需要使用os.path.dirname获取文件目录。
-
储备知识
.在路径中的意思是当前路径
…在路径中的意思是上一层路径
…/…在路径中的意思是上上一层路径 -
相对导入可以不参考执行文件的路径 直接以当前模块文件路径为准
相对导入只能在模块中使用 不能再执行文件中使用
相对导入在项目比较复杂时可能会出错
推荐使用绝对导入
八 包 8.1 包的概念内部有一个__init__.py的文件夹
在python2中如果内部没有__init__.py的文件夹,那么它就不是一个包,而在python3中问价夹中有没有__init__.py都是包
将多个模块(py文件)放在一个文件夹中,方便管理。
8.3 具体使用import 包名
导入包名其实是导入它的__init__.py,该文件中有什么名字才能那个用什么
也可以跨过__init__.py直接导入包里的模块



