Veloris.
返回索引
概念基础 2026-02-14

Python模块与包:import一行引入万千功能,代码组织的正确姿势

3 分钟
895 words

Python模块与包:import一行引入万千功能,代码组织的正确姿势

模块和包是Python代码组织的核心机制,使代码可以被复用和共享。理解import机制、标准库的使用以及第三方库的安装,是Python开发的必备技能。


1. 什么是模块

模块(Module)是一个包含Python代码的.py文件,可以定义函数、类和变量。

# mymodule.py - 这就是一个模块
"""这是模块的文档字符串"""

# 模块级变量
VERSION = "1.0.0"

# 函数
def greet(name):
    return f"Hello, {name}!"

# 类
class Calculator:
    def add(self, a, b):
        return a + b

模块的好处

  • 代码复用:写一次,到处使用
  • 命名空间:避免名称冲突
  • 代码组织:将相关功能放在一起

2. 导入模块

2.1 import语句

# 导入整个模块
import math

print(math.pi)          # 3.141592653589793
print(math.sqrt(16))    # 4.0

# 导入多个模块
import os
import sys
import json

# 或一行导入多个(不推荐)
import os, sys, json

2.2 from…import语句

# 从模块导入特定内容
from math import pi, sqrt

print(pi)          # 3.141592653589793
print(sqrt(16))    # 4.0(不需要math.前缀)

# 导入所有内容(不推荐)
from math import *
print(sin(0))      # 0.0

# 为什么不推荐 import *?
# 1. 不清楚导入了什么
# 2. 可能覆盖已有名称
# 3. 代码可读性差

2.3 导入别名

# 模块别名
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 函数/类别名
from datetime import datetime as dt
now = dt.now()

# 常见的别名约定
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
import seaborn as sns

3. 创建自己的模块

# utils.py - 自定义工具模块
"""
工具函数模块
提供常用的辅助函数
"""

__version__ = "1.0.0"
__author__ = "Your Name"

def add(a, b):
    """两数相加"""
    return a + b

def multiply(a, b):
    """两数相乘"""
    return a * b

def is_even(n):
    """判断是否为偶数"""
    return n % 2 == 0

class MathHelper:
    """数学辅助类"""
    
    @staticmethod
    def factorial(n):
        """计算阶乘"""
        if n <= 1:
            return 1
        return n * MathHelper.factorial(n - 1)

# 模块级别的初始化代码
print("utils模块已加载")
# main.py - 使用自定义模块
import utils

print(utils.add(1, 2))           # 3
print(utils.is_even(4))          # True
print(utils.MathHelper.factorial(5))  # 120

from utils import add, multiply
print(add(3, 4))                 # 7

4. 包(Package)

包是包含多个模块的目录,必须包含__init__.py文件。

mypackage/
├── __init__.py          # 包的初始化文件
├── module1.py
├── module2.py
└── subpackage/          # 子包
    ├── __init__.py
    └── module3.py
# mypackage/__init__.py
"""mypackage包"""
from .module1 import func1
from .module2 import func2

__all__ = ['func1', 'func2']  # 定义 from package import * 导入的内容

# mypackage/module1.py
def func1():
    return "func1 from module1"

# mypackage/module2.py
def func2():
    return "func2 from module2"

# mypackage/subpackage/__init__.py
from .module3 import func3

# mypackage/subpackage/module3.py
def func3():
    return "func3 from subpackage"
# 使用包
import mypackage
print(mypackage.func1())

from mypackage import func1, func2
print(func1())

from mypackage.subpackage import func3
print(func3())

from mypackage.module1 import func1
print(func1())

5. __name__变量

__name__是一个特殊变量,用于判断模块是被导入还是直接运行。

# mymodule.py
def main():
    print("主程序执行")

def helper():
    print("辅助函数")

# 当模块被直接运行时,__name__ == "__main__"
# 当模块被导入时,__name__ == "mymodule"

if __name__ == "__main__":
    # 只有直接运行此文件时才执行
    print("直接运行模块")
    main()
else:
    print(f"模块被导入,__name__ = {__name__}")
# 运行 python mymodule.py
# 输出:直接运行模块
#       主程序执行

# 在其他文件中 import mymodule
# 输出:模块被导入,__name__ = mymodule

典型用法

# calculator.py
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def main():
    """测试代码"""
    print(f"1 + 2 = {add(1, 2)}")
    print(f"5 - 3 = {subtract(5, 3)}")

if __name__ == "__main__":
    main()

6. 模块搜索路径

Python按以下顺序搜索模块:

  1. 当前目录
  2. 环境变量PYTHONPATH中的目录
  3. 标准库目录
  4. site-packages目录(第三方库)
import sys

# 查看模块搜索路径
for path in sys.path:
    print(path)

# 添加自定义搜索路径
sys.path.append('/path/to/my/modules')

# 查看模块位置
import os
print(os.__file__)  # 显示os模块的文件路径

# 查看已导入的模块
print(sys.modules.keys())

7. 标准库概览

Python标准库提供了丰富的功能模块:

类别模块功能
文件/目录os, pathlib, shutil文件系统操作
数据格式json, csv, xml数据序列化
日期时间datetime, time, calendar时间处理
数学math, random, statistics数学计算
字符串re, string, textwrap字符串处理
网络urllib, http, socket网络通信
并发threading, multiprocessing, asyncio并发编程
数据结构collections, itertools, functools高级数据结构
调试logging, pdb, traceback调试和日志
系统sys, os, platform系统交互
# 常用标准库示例

# os - 操作系统接口
import os
print(os.getcwd())           # 当前目录
print(os.listdir('.'))       # 列出目录内容
os.makedirs('new/dir', exist_ok=True)  # 创建目录

# datetime - 日期时间
from datetime import datetime, timedelta
now = datetime.now()
print(now.strftime('%Y-%m-%d %H:%M:%S'))
tomorrow = now + timedelta(days=1)

# json - JSON处理
import json
data = {'name': '张三', 'age': 25}
json_str = json.dumps(data, ensure_ascii=False)
data = json.loads(json_str)

# re - 正则表达式
import re
pattern = r'\d+'
matches = re.findall(pattern, 'abc123def456')

# collections - 高级数据结构
from collections import Counter, defaultdict, namedtuple
counter = Counter(['a', 'b', 'a', 'c', 'a'])
print(counter.most_common(2))  # [('a', 3), ('b', 1)]

# random - 随机数
import random
print(random.randint(1, 100))
print(random.choice(['a', 'b', 'c']))
random.shuffle([1, 2, 3, 4, 5])

# logging - 日志
import logging
logging.basicConfig(level=logging.INFO)
logging.info('这是一条日志')

8. 第三方库安装

使用pip安装第三方库:

# 安装包
pip install package_name
pip install pandas
pip install numpy==1.24.0      # 指定版本
pip install "numpy>=1.20,<2.0" # 版本范围

# 升级包
pip install --upgrade package_name
pip install -U pandas

# 卸载包
pip uninstall package_name

# 查看已安装的包
pip list
pip show pandas  # 查看包详情

# 导出依赖
pip freeze > requirements.txt

# 从文件安装
pip install -r requirements.txt

# 使用国内镜像
pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple

常用第三方库

领域用途
数据处理pandas, numpy数据分析
可视化matplotlib, seaborn图表绑制
Web开发Flask, Django, FastAPIWeb框架
网络请求requestsHTTP客户端
办公自动化openpyxl, python-docx, python-pptxOffice文件
串口通信pyserial串口操作
GUIPyQt5, tkinter图形界面

9. 虚拟环境

虚拟环境为每个项目创建独立的Python环境。

# 创建虚拟环境
python -m venv .venv

# 激活虚拟环境
# Windows CMD
.venv\Scripts\activate
# Windows PowerShell
.venv\Scripts\Activate.ps1
# Linux/Mac
source .venv/bin/activate

# 退出虚拟环境
deactivate

# 在虚拟环境中安装包
pip install pandas

# 导出依赖
pip freeze > requirements.txt

# 在新环境中安装依赖
pip install -r requirements.txt

项目结构示例

my_project/
├── .venv/              # 虚拟环境(不提交到Git)
├── src/
│   ├── __init__.py
│   └── main.py
├── tests/
├── requirements.txt    # 依赖列表
├── README.md
└── .gitignore          # 包含.venv/

10. 常见错误与避坑

❌ 错误1:循环导入

# a.py
from b import func_b
def func_a():
    return "a"

# b.py
from a import func_a  # 循环导入!
def func_b():
    return "b"

# 解决方案:
# 1. 重构代码,消除循环依赖
# 2. 将导入放在函数内部
# 3. 使用延迟导入

❌ 错误2:模块名与标准库冲突

# 错误:创建了名为 random.py 的文件
# 会覆盖标准库的random模块

# 正确:使用不同的名称
# my_random.py 或 random_utils.py

❌ 错误3:相对导入错误

# 在包内使用相对导入
# mypackage/module1.py
from .module2 import func  # 正确
from module2 import func   # 可能出错

# 相对导入只能在包内使用
# 直接运行模块时会报错

❌ 错误4:修改模块后不生效

# 模块只会被导入一次
# 修改后需要重新加载

import importlib
import mymodule

# 重新加载模块
importlib.reload(mymodule)

11. 实战练习

练习1:创建工具包

"""
练习:创建一个工具包,包含文件操作和字符串处理功能

目录结构:
mytools/
├── __init__.py
├── fileutils.py
└── strutils.py
"""

# mytools/__init__.py
from .fileutils import read_file, write_file
from .strutils import clean_text, extract_numbers

__version__ = "1.0.0"
__all__ = ['read_file', 'write_file', 'clean_text', 'extract_numbers']

# mytools/fileutils.py
from pathlib import Path

def read_file(filepath, encoding='utf-8'):
    """读取文件内容"""
    return Path(filepath).read_text(encoding=encoding)

def write_file(filepath, content, encoding='utf-8'):
    """写入文件内容"""
    Path(filepath).write_text(content, encoding=encoding)

# mytools/strutils.py
import re

def clean_text(text):
    """清理文本"""
    return ' '.join(text.split())

def extract_numbers(text):
    """提取文本中的数字"""
    return [int(n) for n in re.findall(r'\d+', text)]

练习2:配置管理模块

"""
练习:创建配置管理模块
"""
# config.py
import json
from pathlib import Path

class Config:
    """配置管理类"""
    
    def __init__(self, config_file='config.json'):
        self.config_file = Path(config_file)
        self._config = {}
        self.load()
    
    def load(self):
        """加载配置"""
        if self.config_file.exists():
            self._config = json.loads(
                self.config_file.read_text(encoding='utf-8')
            )
    
    def save(self):
        """保存配置"""
        self.config_file.write_text(
            json.dumps(self._config, ensure_ascii=False, indent=2),
            encoding='utf-8'
        )
    
    def get(self, key, default=None):
        """获取配置项"""
        return self._config.get(key, default)
    
    def set(self, key, value):
        """设置配置项"""
        self._config[key] = value
        self.save()

# 使用
if __name__ == "__main__":
    config = Config()
    config.set('debug', True)
    config.set('database', {'host': 'localhost', 'port': 3306})
    print(config.get('debug'))

12. 总结

🔑 核心要点

知识点要点
模块一个.py文件就是一个模块
包含__init__.py的目录
import导入整个模块
from…import导入特定内容
__name__判断模块是被导入还是直接运行
pip安装第三方库
虚拟环境项目隔离的Python环境

✅ 学习检查清单

  • 理解模块和包的概念
  • 掌握各种import方式
  • 能创建自己的模块和包
  • 理解__name__的作用
  • 能使用pip安装第三方库
  • 能创建和使用虚拟环境

📖 下一步学习

掌握了模块与包后,让我们学习Python的面向对象编程:


常见问题 FAQ

💬 importfrom...import哪个好?

import module更安全,避免命名冲突。from module import func更方便但要注意重名。大型项目建议用import module然后module.func()调用。

💬 if __name__ == "__main__":有什么用?

这行让文件既可以作为模块被import,也可以直接运行。import时__name__是模块名,直接运行时是"__main__"。几乎每个Python脚本都应该加这行。


系列导航

End of file.