在Python中,**库(Library)、包(Package)和模块(Module)**是代码组织的不同层级,而import
语句的导入行为与它们密切相关。以下是详细对比和解释:
术语 | 定义 | 示例 | 文件结构 |
---|---|---|---|
模块 | 单个.py 文件,包含Python代码(变量、函数、类) |
math.py |
math.py |
包 | 特殊的模块集合,包含__init__.py 文件的目录 |
numpy (文件夹) |
numpy/__init__.py |
库 | 广义概念,指可复用的代码集合(可能包含多个包/模块) | requests 库 |
由多个包/模块组成 |
import
导入的实质import xxx # 导入的是模块/包本身(如`import numpy`)
from xxx import yyy # 从模块/包中导入具体对象(如`from math import sqrt`)
sys
、math
)sys.path
中的路径(包括当前目录、PYTHONPATH等)site-packages
目录)# my_module.py
def hello():
print("Hello from module!")
导入方式:
import my_module
my_module.hello()
my_package/
├── __init__.py # 包标识文件(可为空)
├── module1.py # 子模块
└── subpackage/ # 子包
└── __init__.py
导入方式:
from my_package.module1 import some_function
import numpy
时到底导入了什么?numpy
包的顶层模块(即numpy/__init__.py
中定义的内容)numpy.array
)Pandas
库)pandas
包包含pandas/core
、pandas/io
等子包)__init__.py
?__all__
列表)# 明确导入层级(避免命名冲突)
from package.subpackage import specific_function
# 使用别名简化长包名
import matplotlib.pyplot as plt
# 通配符导入(污染命名空间)
from module import *
# 重复导入相同模块(浪费资源)
import module
import module # 无意义
my_utils/
├── __init__.py # 声明为包
├── math_utils.py # 模块:数学工具
└── string_utils.py # 模块:字符串工具
__init__.py
(控制导入行为):
# 允许直接导入包时访问子模块
from .math_utils import add, multiply
from .string_utils import reverse_string
__all__ = ['add', 'multiply', 'reverse_string'] # 定义*导入的范围
使用方式:
import my_utils
my_utils.add(1, 2) # 直接调用
from my_utils import reverse_string
reverse_string("abc") # 'cba'
概念 | 本质 | import 行为 |
典型用途 |
---|---|---|---|
模块 | 单个.py 文件 |
导入文件中的所有代码 | 组织小规模功能 |
包 | 含__init__.py 的目录 |
导入包初始化内容或子模块 | 组织大型项目代码 |
库 | 功能集合的抽象概念 | 通过导入其下的包/模块使用 | 指代第三方功能集合 |
理解这些区别有助于: