Day 34 模块和库的导入

@浙大疏锦行

一、导入官方库的三种手段

在 Python 中,导入官方标准库(如 mathossysjson 等)的核心手段有三类,分别适配不同的使用场景(如简化代码、明确命名空间、轻量化调用)。以下是详细讲解,结合官方库示例说明:

核心手段 1:直接导入模块(import 模块名

这是最基础、最推荐的导入方式,完整导入整个模块,使用模块内的属性 / 方法时需通过「模块名。属性」的形式调用,命名空间清晰

语法
复制代码
import 模块名

示例(以官方 math 库为例)

复制代码
# 导入官方math库
import math

# 使用模块的常量/方法(必须加模块名前缀)
print(math.pi)          # 访问圆周率常量 → 3.141592653589793
print(math.sqrt(16))    # 调用平方根方法 → 4.0
print(math.cos(math.pi))# 调用余弦方法 → -1.0

优点 & 适用场景

  • 优点:避免同名冲突(如 math.sqrtnumpy.sqrt 可明确区分),代码可读性高;
  • 适用场景:需要使用模块中多个属性 / 方法 ,或模块名较短(如 mathos)时。

核心手段 2:导入模块并指定别名(import 模块名 as 别名

当模块名较长(如 datetimecollections),或需要简化高频调用的模块时,给模块指定别名,调用时用别名替代原模块名。

语法
复制代码
import 模块名 as 别名

示例(以官方 sysjson 库为例)

复制代码
# 给官方库指定别名
import sys as system       # sys(系统相关)→ 别名system
import json as js          # json(数据序列化)→ 别名js

# 使用别名调用
print(system.version)      # 查看Python版本(等价于sys.version)
data = {"name": "Alice"}
print(js.dumps(data))      # 序列化字典(等价于json.dumps)

优点 & 适用场景

  • 优点:简化代码书写,尤其适合高频使用的模块;
  • 通用约定:官方库无强制别名(第三方库如 numpy 常用 np),按需自定义即可;
  • 适用场景:模块名较长(如 import collections as coll),或需区分同名模块时。

核心手段 3:从模块中导入指定属性 / 方法(from ... import ...

直接导入模块内的特定属性、方法或类,使用时无需加模块名前缀,更轻量化。分为 3 个子形式:

子形式 1:导入指定单个 / 多个属性

语法
复制代码
from 模块名 import 方法1, 方法2, 常量1
示例(以 math 库为例)
复制代码
# 仅导入math库的pi常量和cos方法
from math import pi, cos

# 直接使用,无需math.前缀
print(pi)       # → 3.141592653589793
print(cos(0))   # → 1.0

子形式 2:导入并给属性指定别名(解决同名冲突)

语法
复制代码
from 模块名 import 方法/常量 as 别名
示例
复制代码
# 给math.sqrt指定别名square_root,避免与自定义sqrt冲突
from math import sqrt as square_root

# 自定义一个sqrt方法(不会冲突)
def sqrt(num):
    return f"自定义平方根:{num **0.5}"

print(square_root(25))  # 调用math.sqrt → 5.0
print(sqrt(25))         # 调用自定义sqrt → 自定义平方根:5.0

子形式 3:导入模块所有属性(慎用 from ... import *

语法
复制代码
from 模块名 import *
示例
复制代码
# 导入math库所有属性/方法(不推荐生产代码使用)
from math import *

print(sin(pi/2))  # 直接调用sin方法 → 1.0
print(log(10))    # 直接调用对数方法 → 2.302585093
缺点 & 适用场景
  • 缺点:命名空间污染(易与自定义变量同名)、代码可读性差(无法判断属性所属模块);
  • 适用场景:仅临时测试 / 交互式终端(如 Python 命令行),生产代码严禁使用

二、导入自定义库 / 模块的核心方式

Python 导入自定义模块的语法与导入官方库完全一致(复用 import/from...import 体系),核心差异在于让解释器找到自定义模块的路径。以下是最常用的导入方式,结合自定义模块示例讲解:

前提:先定义自定义模块

假设项目目录结构如下(后续示例基于此结构):

复制代码
my_project/
├── main.py          # 主程序(执行入口)
├── utils.py         # 自定义模块(同级)
└── calc/            # 自定义包(含多个模块)
    ├── __init__.py  # 包标识文件(空文件即可)
    ├── circle.py    # 子模块:圆相关计算
    └── rect.py      # 子模块:长方形相关计算

utils.py 内容:

复制代码
# utils.py
def add(a, b):
    return a + b

PI = 3.14159

calc/circle.py 内容:

复制代码
# calc/circle.py
from utils import PI  # 包内调用同级模块
def circle_area(radius):
    return PI * radius **2

1. 导入同级自定义模块(最基础)

适用于主程序与自定义模块在同一目录 (如 main.py 导入 utils.py)。

方式 1:直接导入模块(推荐,命名空间清晰)
复制代码
# main.py
import utils  # 导入同级的utils.py模块

# 使用:模块名.属性/方法
print(utils.add(2, 3))  # → 5
print(utils.PI)         # → 3.14159
方式 2:导入模块并指定别名
复制代码
# main.py
import utils as ut  # 给utils指定别名ut

print(ut.add(4, 5))  # → 9
方式 3:导入模块内指定属性 / 方法
复制代码
# main.py
from utils import add, PI  # 仅导入指定属性
# 或给属性指定别名
from utils import add as plus

print(add(10, 20))  # → 30
print(plus(5, 5))   # → 10
print(PI)           # → 3.14159

2. 导入自定义包内的子模块

适用于模块按目录组织为「包」(如 main.py 导入 calc 包下的 circle.py)。

方式 1:导入包。子模块
复制代码
# main.py
import calc.circle  # 导入calc包下的circle子模块

print(calc.circle.circle_area(5))  # → 78.53975
方式 2:导入包。子模块并指定别名方式 3:从包中导入子模块 / 属性
复制代码
# main.py
from calc import circle  # 从calc包导入circle子模块
from calc.circle import circle_area  # 从子模块导入具体方法

print(circle.circle_area(4))  # → 50.26544
print(circle_area(2))         # → 12.56636

3. 导入不同目录的自定义模块(跨目录)

若自定义模块不在主程序同级目录(如 main.py 要导入 ../other_dir/tool.py),需先将模块所在目录加入 Python 解释器的「搜索路径」。

场景示例:
复制代码
my_project/
├── main.py
└── other_dir/
    └── tool.py  # 需导入的跨目录模块

tool.py 内容:

复制代码
# tool.py
def multiply(a, b):
    return a * b
解决方法:
方法 1:临时添加路径(运行时生效)
复制代码
# main.py
import sys
import os

# 将other_dir目录的绝对路径加入sys.path
sys.path.append(os.path.abspath("./other_dir"))

# 此时可正常导入tool模块
import tool
print(tool.multiply(3, 4))  # → 12
方法 2:将自定义模块设为「可安装包」(推荐生产环境)

通过 setup.pypyproject.toml 将自定义包安装为「开发模式」,使其被 Python 全局识别(略,适合大型项目)。


三、导入库 / 模块的核心逻辑

Python 导入模块的本质是「找到模块文件 → 加载并执行模块代码 → 创建模块对象 → 绑定到当前命名空间」,核心分为 4 步:

步骤 1:解析导入语法,确定目标模块名

无论导入官方库还是自定义模块,解释器首先解析 import 语句,提取「模块全名」:

  • import utils → 目标模块名:utils
  • import calc.circle → 目标模块名:calc.circle
  • from utils import add → 先定位 utils 模块,再提取 add 属性。
步骤 2:搜索模块文件(核心:sys.path 路径列表)

Python 解释器会按顺序在 sys.path 列表中的目录里查找模块文件,sys.path 包含以下路径(优先级从高到低):

  1. 主程序所在目录(当前工作目录 os.getcwd());
  2. Python 内置库目录(如 .../python3.x/lib);
  3. 第三方库安装目录(如 site-packages);
  4. 手动添加的路径(sys.path.append(...))。

注:模块文件的后缀可以是 .py.pyc(编译后的字节码),包则需要包含 __init__.py(Python 3.3+ 后可省略,但推荐保留)。

步骤 3:加载并执行模块代码(仅首次导入时执行)

找到模块文件后,解释器会:

  • 读取文件内容,编译为字节码;
  • 执行模块代码(因此模块顶层的代码会在导入时运行,如 print()、变量定义);
  • 创建一个「模块对象」(类型为 module),将模块内的属性(函数、变量、类)绑定到该对象。

关键特性:模块是「单例」的 ------ 同一模块无论导入多少次,仅加载 / 执行一次,后续导入直接复用已创建的模块对象。

步骤 4:将模块 / 属性绑定到当前命名空间

根据导入语法,将模块对象或其属性映射到当前代码的命名空间:

  • import utils → 命名空间中新增 utils 变量,指向模块对象;
  • from utils import add → 命名空间中新增 add 变量,直接指向 utils 模块里的 add 函数;
  • import utils as ut → 命名空间中新增 ut 变量,指向 utils 模块对象。

四、关键注意事项

  1. 避免循环导入 :两个模块互相导入对方(如 a.py import bb.py import a)会导致导入失败,解决方法:
    • 将导入语句移到函数内部(懒加载);
    • 提取公共代码到新模块;
  2. 命名空间污染from 模块 import * 会将模块所有属性导入当前命名空间,易与自定义变量冲突,生产代码禁用;
  3. 包的 init.py 作用
    • 标识目录为 Python 包;
    • 可在其中定义包的公共接口(如 __all__ = ["circle", "rect"],控制 from calc import * 导入的子模块);
  4. 模块缓存 :导入后的模块会被缓存到 sys.modules 字典中,若修改模块代码后需重新导入,需先 del sys.modules["模块名"] 再重新导入。
相关推荐
草莓熊Lotso1 小时前
Python 进阶核心:字典 / 文件操作 + 上下文管理器实战指南
数据结构·c++·人工智能·经验分享·笔记·git·python
天远Date Lab1 小时前
Python实现用户消费潜力评估:天远个人消费能力等级API对接全攻略
java·大数据·网络·python
秃了也弱了。9 小时前
python实现定时任务:schedule库、APScheduler库
开发语言·python
Dfreedom.9 小时前
从 model(x) 到__call__:解密深度学习框架的设计基石
人工智能·pytorch·python·深度学习·call
weixin_425023009 小时前
Spring Boot 配置文件优先级详解
spring boot·后端·python
小徐Chao努力10 小时前
【Langchain4j-Java AI开发】06-工具与函数调用
java·人工智能·python
无心水10 小时前
【神经风格迁移:全链路压测】33、全链路监控与性能优化最佳实践:Java+Python+AI系统稳定性保障的终极武器
java·python·性能优化
luoluoal11 小时前
基于python的小区监控图像拼接系统(源码+文档)
python·mysql·django·毕业设计·源码
BoBoZz1911 小时前
MotionBlur 演示简单运动模糊
python·vtk·图形渲染·图形处理
十八度的天空12 小时前
第01节 Python的基础语法
开发语言·python