Skip to content

模块与包管理

组织代码,复用功能 —— 构建可维护的项目


什么是模块?

模块(Module) = 一个 .py 文件 包(Package) = 包含 __init__.py 的文件夹

类比

  • Stata: .ado 文件
  • R: Package(如 dplyr, ggplot2

导入模块

1. 导入整个模块

python
import math

print(math.sqrt(16))  # 4.0
print(math.pi)        # 3.141592653589793
print(math.log(100))  # 4.605...

2. 导入并重命名

python
import pandas as pd  # 标准做法
import numpy as np
import matplotlib.pyplot as plt

df = pd.DataFrame({'x': [1, 2, 3]})

3. 导入特定函数

python
from math import sqrt, pi, log

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

4. 导入所有(不推荐)

python
from math import *  #  不推荐,可能覆盖已有变量

#  推荐明确导入
from math import sqrt, pi, log

常用标准库

1. math:数学运算

python
import math

# 基本函数
math.sqrt(16)      # 平方根
math.log(100)      # 自然对数
math.log10(100)    # 以10为底的对数
math.exp(2)        # e^2
math.pow(2, 3)     # 2^3

# 三角函数
math.sin(math.pi / 2)  # 1.0
math.cos(0)            # 1.0

# 常数
math.pi   # 3.14159...
math.e    # 2.71828...

2. statistics:统计

python
import statistics as stats

data = [85, 92, 78, 90, 88]

stats.mean(data)      # 平均值
stats.median(data)    # 中位数
stats.mode(data)      # 众数
stats.stdev(data)     # 标准差
stats.variance(data)  # 方差

3. random:随机数

python
import random

# 随机整数
random.randint(1, 10)      # 1-10 的随机整数

# 随机浮点数
random.random()            # 0-1 之间
random.uniform(1, 10)      # 1-10 之间

# 随机选择
majors = ['Economics', 'Sociology', 'Political Science']
random.choice(majors)      # 随机选一个

# 随机抽样
random.sample(majors, 2)   # 不放回抽2个

# 打乱列表
data = [1, 2, 3, 4, 5]
random.shuffle(data)       # 原地打乱

社科应用:随机分组

python
import random

participants = list(range(1, 101))  # 100个参与者
random.shuffle(participants)

# 分为实验组和对照组
treatment = participants[:50]
control = participants[50:]

print(f"实验组: {len(treatment)} 人")
print(f"对照组: {len(control)} 人")

4. datetime:日期时间

python
from datetime import datetime, timedelta

# 当前时间
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"))

# 日期运算
survey_start = datetime(2024, 1, 1)
survey_end = survey_start + timedelta(days=365)
duration = survey_end - survey_start
print(f"调查周期: {duration.days} 天")

# 解析日期
date_str = "2024-03-15"
date_obj = datetime.strptime(date_str, "%Y-%m-%d")

5. json:JSON 数据

python
import json

# 字典转 JSON
data = {
    'respondent_id': 1001,
    'age': 30,
    'income': 75000
}

json_str = json.dumps(data, indent=2)
print(json_str)

# JSON 转字典
parsed = json.loads(json_str)
print(parsed['age'])  # 30

创建自己的模块

示例:创建 survey_utils.py

python
# survey_utils.py
"""问卷数据处理工具模块"""

def calculate_response_rate(collected, target):
    """计算回收率"""
    return (collected / target) * 100

def validate_age(age):
    """验证年龄"""
    return 0 < age < 120

def income_to_category(income):
    """收入分类"""
    if income < 50000:
        return "低收入"
    elif income < 100000:
        return "中收入"
    else:
        return "高收入"

# 模块级常量
VALID_GENDERS = ["Male", "Female", "Other"]
MIN_AGE = 18
MAX_AGE = 100

使用自定义模块

python
# main.py
import survey_utils

# 使用函数
rate = survey_utils.calculate_response_rate(850, 1000)
print(f"回收率: {rate:.1f}%")

is_valid = survey_utils.validate_age(25)
category = survey_utils.income_to_category(75000)

# 使用常量
print(survey_utils.VALID_GENDERS)

包结构

my_project/
├── data_processing/
│   ├── __init__.py
│   ├── cleaning.py
│   └── validation.py
├── analysis/
│   ├── __init__.py
│   ├── descriptive.py
│   └── regression.py
└── main.py

导入包中的模块

python
# main.py
from data_processing import cleaning
from data_processing.validation import validate_age
from analysis.descriptive import calculate_mean

# 使用
cleaned_data = cleaning.remove_outliers(raw_data)
is_valid = validate_age(25)
mean = calculate_mean([1, 2, 3, 4, 5])

第三方包管理

pip:包管理器

bash
# 安装包
pip install pandas
pip install numpy matplotlib

# 安装特定版本
pip install pandas==1.5.3

# 批量安装
pip install -r requirements.txt

# 查看已安装
pip list

# 卸载
pip uninstall pandas

requirements.txt

pandas==1.5.3
numpy==1.24.3
matplotlib==3.7.1
scikit-learn==1.2.2
statsmodels==0.14.0

虚拟环境

bash
# 创建虚拟环境
python -m venv myenv

# 激活(Mac/Linux)
source myenv/bin/activate

# 激活(Windows)
myenv\Scripts\activate

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

# 导出依赖
pip freeze > requirements.txt

# 退出
deactivate

实战:项目结构

income_survey_project/
├── data/
│   ├── raw/
│   │   └── survey_responses.csv
│   └── processed/
│       └── clean_data.csv
├── src/
│   ├── __init__.py
│   ├── data_cleaning.py
│   ├── statistical_analysis.py
│   └── visualization.py
├── tests/
│   ├── test_cleaning.py
│   └── test_analysis.py
├── notebooks/
│   ├── exploratory_analysis.ipynb
│   └── final_report.ipynb
├── outputs/
│   ├── figures/
│   └── tables/
├── main.py
├── requirements.txt
└── README.md

src/data_cleaning.py

python
"""数据清洗模块"""
import pandas as pd

def remove_outliers(df, column, lower=0.01, upper=0.99):
    """移除离群值"""
    q_low = df[column].quantile(lower)
    q_high = df[column].quantile(upper)
    return df[(df[column] >= q_low) & (df[column] <= q_high)]

def validate_responses(df):
    """验证响应数据"""
    valid_mask = (
        (df['age'] >= 18) &
        (df['age'] <= 100) &
        (df['income'] >= 0)
    )
    return df[valid_mask]

main.py

python
"""主程序"""
import pandas as pd
from src.data_cleaning import remove_outliers, validate_responses
from src.statistical_analysis import calculate_descriptive_stats
from src.visualization import plot_income_distribution

# 读取数据
df = pd.read_csv('data/raw/survey_responses.csv')

# 清洗
df = validate_responses(df)
df = remove_outliers(df, 'income')

# 分析
stats = calculate_descriptive_stats(df)
print(stats)

# 可视化
plot_income_distribution(df, save_path='outputs/figures/income_dist.png')

最佳实践

1. 导入顺序

python
# 1. 标准库
import os
import sys
from datetime import datetime

# 2. 第三方库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 3. 自己的模块
from src.data_cleaning import remove_outliers
from src.analysis import calculate_mean

2. 避免循环导入

python
#  错误:A 导入 B,B 又导入 A
# module_a.py
from module_b import func_b

# module_b.py
from module_a import func_a  # 循环导入!

#  解决方法:将共同依赖提取到第三个模块

3. if __name__ == "__main__"

python
# my_module.py
def calculate_mean(data):
    return sum(data) / len(data)

# 模块级测试代码
if __name__ == "__main__":
    # 只在直接运行时执行
    test_data = [1, 2, 3, 4, 5]
    print(calculate_mean(test_data))

练习题

练习 1:创建工具模块

python
# 创建 stats_utils.py 模块,包含:
# 1. calculate_mean(data)
# 2. calculate_median(data)
# 3. calculate_variance(data)
# 4. CONFIDENCE_LEVEL = 0.95(常量)

# 然后在另一个文件中导入并使用

练习 2:数据处理流水线

python
# 创建包结构:
# data_pipeline/
#   __init__.py
#   cleaning.py  # 数据清洗函数
#   transform.py # 数据转换函数
#   export.py    # 导出函数

# 在 main.py 中使用完整流水线

总结

你现在掌握了:

  • 函数定义和调用
  • 参数传递(位置、关键字、可变)
  • Lambda 函数
  • 模块和包管理

下一个模块:我们将学习 面向对象编程基础

准备好了吗?

基于 MIT 许可证发布。内容版权归作者所有。