day30 模块和库的导入
目录
导入官方库
标准导入:导入整个库
从库中导入特定项
非标准导入:导入整个库
模块、包的定义
模块(module)
包(package)
使用案例
场景1:main.py和circle.py都在同一目录
场景2:main.py和circle.py都在根目录的子目录model/下
场景3:main.py在根目录,circle.py在子目录model/下
场景4:main.py和circle.py在两个不同的子目录下(跨目录)
导入官方库
我们复盘下学习python的逻辑,所谓学习python就是学习python常见的基础语法+学习你所处理任务需要用到的第三方库。
标准导入:导入整个库
这是最基本也是最常见的导入方式,直接使用import语句
# 方式1:导入整个模块
import mathprint("方式1:使用 import math")
print(f"圆周率π的值:{math.pi}")
print(f"2的平方根:{math.sqrt(2)}\n")
方式1:使用 import math
圆周率π的值:3.141592653589793
2的平方根:1.4142135623730951
从库中导入特定项
当使用from语法从库中导入特定的函数或类时,这些函数或类就可以在您的代码中直接使用,不需要添加模块名作为前缀。因为在导入时没有包括模块的完整路径,前面也不能加上库名。
# 方式2:导入特定的函数或变量
from math import pi, sqrtprint("方式2:使用 from math import pi, sqrt")
print(f"圆周率π的值:{pi}")
print(f"2的平方根:{sqrt(2)}\n")
方式2:使用 from math import pi, sqrt
圆周率π的值:3.141592653589793
2的平方根:1.4142135623730951
类似的写法,如sklearn库很大,直接导入sklearn库会占用电脑大量内存,所以一般只导入你需要的库,
- 如:from sklearn.model_selection import train_test_split
非标准导入:导入整个库
如下,这将导入math模块中定义的所有公开函数和变量。和上述from同理,直接调用sin(),cos()等,而无需math.前缀。
虽然import math和from math import * 看起来都是导入了math模块,但是它们在导入方式、作用域处理以及对命名空间的影响上有重要的区别。
1.命名空间的污染
import math:这种方法会将整个math模块导入到命名空间中,但是需要使用math.前缀来访问模块内的函数或变量。这种方式博啊值了命名空间的整洁,因为所有的math函数和变量都包含在math这个模块对象中。
from math import *:这种方法将math模块中所有公开的函数和变量导入到当前的命名空间中,可以直接使用这些函数和变量无需math.前缀。这种方式可能会导致命名空间污染,特别是当有多个模块都被这样导入时,很容易发生命名冲突。
2.明确性和可维护性
import math:明确指出了函数和变量来源于math模块,这对代码的可读性和维护性都是有益的。其他阅读你代码的人可以清楚地看到每个函数的来源,这对大型项目和团队合作尤为重要。
from math import *:虽然代码看起来更简洁,但这种方法减少了代码的明确性。如果没有足够的上下文,很难判断一个特定的函数是来自math模块还是其他模块,尤其是当你导入了多个模块时。
from math import *print(f"圆周率π的值:{pi}")
print(f"2的平方根:{sqrt(2)}")
上述这些,如果是python内置库,可以直接导入,大部分第三方库都需要先用pip来安装。下面的模块,有就是.py文件,是不需要安装即可调用的。
模块、包的定义
模块(module)
- 本质:以.py为结尾的单个文件,包含python代码(函数、类、变量等)。
- 作用:将代码拆分到不同文件中,避免代码冗余,方便复用和维护。
包(package)
在python里,包就是库
- 本质:有层次的文件目录结构(即文件夹),用于组织多个模块和子包。
- 核心特征:包的根目录下必须包含一个__init__.py文件(可以为空),用于标识该目录是一个包。
使用案例
如编写一个计算圆面积的代码并保存为circle.py,这个文件就是一个模块。
使用时通过import circle 导入模块,调用其中的函数。
# circle.py
import mathdef calculate_area(radius):return math.pi * radius ** 2
IDE(如VSCode或PyCharm)通常会将你打开的项目文件夹设为“根目录”(或者说运行时的工作目录)。Python在导入模块时,会从这个根目录(以及其他一些标准位置和脚本所在的目录)开始查找。
场景1:main.py和circle.py都在同一目录
目录结构:
项目根目录/
├── main.py
└── circle.py
# main.py
from circle import calculate_area
# 或者: import circle (然后用 circle.calculate_area)radius = 5
area = calculate_area(radius)
print(f"半径为 {radius} 的圆,面积是: {area}")
运行方案:直接在终端python main.py
场景2:main.py和circle.py都在根目录的子目录model/下
目录结构:
项目根目录/
└── model/
├── __init__.py (推荐添加,将 model 目录标记为包)
├── main.py
└── circle.py
# model/main.py
from circle import calculate_area
# 或者: import circle (然后用 circle.calculate_area)radius = 5
area = calculate_area(radius)
print(f"半径为 {radius} 的圆,面积是: {area}")
运行方案:
1.运行命令:python model/main.py
2.进入路径:cd xxx(main的相对路径),然后执行python main.py(注意如果先cd后,就不能采用第一个命令了)
场景3:main.py在根目录,circle.py在子目录model/下
目录结构:
项目根目录/
├── main.py
└── model/
├── __init__.py (必需添加,将 model 目录标记为一个可导入的包)
└── circle.py
# main.py
from model.circle import calculate_area
# 或者: from model import circle (然后用 circle.calculate_area,因为此时你是导入了整个模块)radius = 5
area = calculate_area(radius)
print(f"半径为 {radius} 的圆,面积是: {area}")
运行方法:python 直接在终端python main.py
场景4:main.py和circle.py在两个不同的子目录下(跨目录)
项目根目录/
├── circle2.py
└── utils/
├── __init__.py (必需添加,将 model 目录标记为一个可导入的包)
└── circle.py
└── model/
└── main.py
from utils import circle # 这是根目录绝对路径的导入方式radius = 5
area = circle.calculate_area(radius)
print(f"半径为 {radius} 的圆,面积是: {area}")
python解释器会自动在sys.path中的目录中搜索模块,因为utils并不在model这个路径下,所以直接运行会报错。
有2类策略:
1.把utile路径加入sys.path中
2.把py文件的终端中直接用python - model.main运行,这种导入方法会默认从根目录开始查找。
ps:之所以你会感觉终端的命令明明是根目录,但是运行时却找不到,是因为python解释器理解的目录和终端的目录不一样通过sys.path可以查看解释器理解的目录。
import sys
for i in sys.path:print(i)
/opt/anaconda3/envs/study/lib/python39.zip /opt/anaconda3/envs/study/lib/python3.9 /opt/anaconda3/envs/study/lib/python3.9/lib-dynload /opt/anaconda3/envs/study/lib/python3.9/site-packages /opt/anaconda3/envs/study/lib/python3.9/site-packages/setuptools/_vendor
import sys
import osproject_root = os.path.abspath(os.path.join(os.getcwd(), '..'))
project_root
'/Users/wangbinhao/Desktop/python学习/day30 模块和包的导入/使用场景4'
# 如果项目根目录不在 sys.path 中,则添加它 (通常添加到开头,优先搜索)
if project_root not in sys.path:sys.path.insert(0, project_root)
sys.path
['/Users/wangbinhao/Desktop/python学习/day30 模块和包的导入/使用场景4', '/opt/anaconda3/envs/study/lib/python39.zip', '/opt/anaconda3/envs/study/lib/python3.9', '/opt/anaconda3/envs/study/lib/python3.9/lib-dynload', '', '/opt/anaconda3/envs/study/lib/python3.9/site-packages', '/opt/anaconda3/envs/study/lib/python3.9/site-packages/setuptools/_vendor']
所以导入包的核心就是找到目录,只有理解了python解释器的目录关系,才能导入包,如果py文件中导入失败,不妨多调试几次路径即可。
@浙大疏锦行