【学Python自动化】 6.1 Python 模块系统学习笔记 (与 Rust 对照)
一、模块基础
什么是模块?
-
Python: .py 文件,包含定义和语句
-
Rust: .rs 文件,使用 mod 关键字声明
Python:
# fibo.py - 自动成为模块
def fib(n):a, b = 0, 1while a < n:print(a, end=' ')a, b = b, a + b
Rust:
// fibo.rs - 需要显式声明
pub fn fib(n: u32) {let (mut a, mut b) = (0, 1);while a < n {print!("{} ", a);(a, b) = (b, a + b);}
}
二、模块详解
导入/使用方式对比
- 基本导入
Python:
import fibo
fibo.fib(1000)
Rust:
mod fibo; // 声明模块
use fibo::fib; // 导入函数fn main() {fib(1000);
}
- 导入特定函数
Python:
from fibo import fib
fib(500)
Rust:
use fibo::fib; // 直接使用函数名
fib(500);
- 使用别名
Python:
import fibo as fib
fib.fib(500)
Rust:
use fibo as fib; // 模块别名
fib::fib(500);use fibo::fib as fibonacci; // 函数别名
fibonacci(500);
模块特性对比
特性 | Python | Rust |
---|---|---|
文件即模块 | 自动 | 需要 mod 声明 |
命名空间 | 每个模块独立 | 每个模块独立 |
访问控制 | 默认公开 | 默认私有,需要 pub |
初始化 | 第一次导入时执行 | 编译时确定 |
1 以脚本方式执行模块
双重用途模式对比
Python:
if __name__ == "__main__":import sysfib(int(sys.argv[1]))
Rust: (需要 main 函数)
// fibo.rs
pub fn fib(n: u32) { /* ... */ }fn main() {let args: Vec<String> = std::env::args().collect();if let Some(n) = args.get(1) {fib(n.parse().unwrap());}
}
2 模块搜索路径
路径解析对比
Python:
import sys
sys.path.append('/my/module/path') # 运行时动态添加
Rust: (在 Cargo.toml 中配置)
[dependencies]
my_crate = { path = "/my/crate/path" }
或者使用 mod 声明:
#[path = "/my/module/path"]
mod custom_module;
3 编译文件
编译缓存对比
Python:
- .pyc 文件在 pycache/
- 自动管理,透明使用
Rust:
-
target/ 目录存放编译结果
-
需要显式编译:cargo build
三、标准模块/库
标准库使用对比
Python:
import sys
import os
import json
Rust:
use std::env;
use std::fs;
use std::collections::HashMap;
四、查看可用内容
introspection 对比
Python: (动态查看)
import fibo
print(dir(fibo)) # 查看所有属性
Rust: (静态文档)
cargo doc --open # 生成文档
或者使用 IDE 的自动补全功能。
五、包(Package)系统对比
项目结构对比
Python 项目结构:
myproject/__init__.pymodule1.pysubpackage/__init__.pymodule2.py
Rust 项目结构:
myproject/Cargo.tomlsrc/lib.rs # 库包根模块main.rs # 二进制包根模块module1.rssubpackage/mod.rs # 子模块声明module2.rs
导入/导出对比
Python 导出:
# __init__.py
from .module1 import some_function
from .subpackage import module2__all__ = ['some_function', 'module2']
Rust 导出:
// lib.rs
pub mod module1;
pub mod subpackage;// 重新导出
pub use module1::some_function;
pub use subpackage::module2;
1 通配符导入对比
Python: (谨慎使用)
from sound.effects import * # 导入所有
Rust: (更明确)
use sound::effects::*; // 导入所有公共项
Rust 的偏好方式:
use sound::effects::{echo, surround}; // 明确导入
2 相对导入对比
Python 相对导入:
from . import echo # 当前包
from .. import formats # 上级包
Rust 相对导入:
use super::echo; // 父模块
use self::formats; // 当前模块
use crate::sound::effects; // 从包根开始
3 模块路径配置
Python 动态路径:
import sys
sys.path.append('/custom/path')
Rust 静态路径:
#[path = "/custom/path/module.rs"]
mod custom_module;
或者在 Cargo.toml 中配置依赖路径。
五、⚡ 核心差异总结
- 哲学差异
-
Python: 动态、灵活、隐式
-
Rust: 静态、明确、显式
- 访问控制
-
Python: 默认都是公开的
-
Rust: 默认私有,需要 pub 关键字
- 模块声明
-
Python: 文件系统驱动,自动发现
-
Rust: 需要显式 mod 声明
- 包管理
-
Python: pip + 虚拟环境
-
Rust: cargo + 工作空间
- 编译模型
-
Python: 解释执行,运行时加载
-
Rust: 静态编译,链接时解析
六、🔧 转换思维建议
从 Rust 到 Python
-
忘记 mod 声明:Python 自动发现文件
-
忘记 pub 关键字:Python 默认都是公开的
-
利用动态特性:dir()、动态导入等
-
接受隐式:Python 很多东西是隐式的
从 Python 到 Rust
-
显式声明一切:模块、可见性、类型
-
理解所有权:Rust 的模块系统与所有权紧密相关
-
利用静态检查:编译器会帮你发现很多问题
-
学习 Cargo:Rust 的包管理器更强大
七、💡 实用对照表
| 操作 | Python | Rust |
| 创建模块 | 创建 .py 文件 | 创建 .rs 文件 + mod 声明 |
| 导入模块 | import module | use module |
| 导出函数 | 默认公开 | pub fn function() |
| 相对导入 | from . import module | use super::module |
| 包管理 | pip install | cargo add |
| 查看内容 | dir(module) | IDE 补全或 cargo doc |
Python 的模块系统更加动态和灵活,而 Rust 的模块系统更加静态和明确。两者各有优势,Python 适合快速开发,Rust 适合构建可靠的大型系统。