Python教程: sys模块入门学习

📚 目录

  1. [sys 模块是什么](#sys 模块是什么)
  2. [命令行参数 sys.argv](#命令行参数 sys.argv)
  3. [模块搜索路径 sys.path](#模块搜索路径 sys.path)
  4. [程序退出 sys.exit ()](#程序退出 sys.exit ())
  5. 标准输入输出流
  6. 版本与平台检测
  7. 内存与递归控制
  8. 异常处理
  9. 完整实战案例
  10. 常见问题与避坑
  11. 速查表
  12. 总结

一、sys 模块是什么

sys 是 Python 标准库中最核心的模块,全称 "System-specific"。它提供了与 Python 解释器直接交互的接口。

1.1 为什么需要它?

表格

场景 解决方案
脚本启动时传参数 sys.argv
控制模块导入路径 sys.path
程序退出返回状态码 sys.exit()
输出重定向到文件 sys.stdout
判断操作系统 sys.platform

1.2 快速上手

python

运行

复制代码
import sys

# 查看所有功能
print(dir(sys))

# 查看Python版本
print(sys.version)

二、命令行参数 sys.argv

sys.argv 是一个列表,存储命令行执行脚本时传入的所有参数。

2.1 基本用法

python

运行

复制代码
# script.py
import sys

print(sys.argv)

运行效果

bash

运行

复制代码
python script.py hello 123 --name
# 输出: ['script.py', 'hello', '123', '--name']

2.2 参数解析

表格

索引 含义
sys.argv[0] 脚本文件名
sys.argv[1] 第一个参数
sys.argv[2:] 剩余所有参数

2.3 实用示例

python

运行

复制代码
import sys

# 获取参数(带默认值)
if len(sys.argv) < 2:
    name = "游客"
else:
    name = sys.argv[1]

print(f"你好, {name}!")

# 数字参数需要转换
if len(sys.argv) > 2:
    try:
        age = int(sys.argv[2])
        print(f"年龄: {age}")
    except ValueError:
        print("年龄必须是数字")

2.4 简单命令行工具

python

运行

复制代码
import sys

args = sys.argv[1:]

if not args:
    print("用法: python tool.py [--help] [--version]")
    sys.exit(1)

for arg in args:
    if arg == "--help":
        print("这是一个示例工具")
    elif arg == "--version":
        print("版本 1.0")
    else:
        print(f"未知参数: {arg}")

三、模块搜索路径 sys.path

sys.path 是一个列表,存储 Python 查找模块的所有路径。

3.1 查看所有路径

python

运行

复制代码
import sys

# 遍历打印所有模块搜索路径
for path in sys.path:
    print(path)

3.2 路径顺序

Python 按 sys.path顺序查找模块,找到第一个就停止:

  1. 当前脚本所在目录
  2. 环境变量 PYTHONPATH 配置的路径
  3. 系统默认安装目录

3.3 添加自定义路径

python

运行

复制代码
import sys

# 添加到末尾(低优先级)
sys.path.append('/my/modules')

# 添加到开头(最高优先级)
sys.path.insert(0, '/priority/modules')

3.4 临时添加路径(推荐)

python

运行

复制代码
import sys
import contextlib

@contextlib.contextmanager
def add_to_path(path):
    """临时添加路径,用完自动移除"""
    try:
        sys.path.insert(0, path)
        yield
    finally:
        sys.path.remove(path)

# 使用方式
with add_to_path('/tmp/my_lib'):
    import my_module  # 从临时路径导入

3.5 查看已加载模块

python

运行

复制代码
import sys

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

# 检查模块是否已加载
if 'requests' in sys.modules:
    print("requests 已加载")

四、程序退出 sys.exit ()

用于主动终止 Python 程序,支持返回状态码和退出提示。

4.1 基本用法

python

运行

复制代码
import sys

# 正常退出(状态码 0)
sys.exit()      
sys.exit(0)     

# 错误退出(状态码 1)
sys.exit(1)     

# 带信息退出
sys.exit("程序出错了") 

4.2 状态码约定

表格

状态码 含义
0 程序执行成功
1 一般业务错误
2 命令行参数错误
130 用户手动中断(Ctrl+C)

4.3 实战示例

python

运行

复制代码
import sys

def process_file(filename):
    """处理文件,失败时退出"""
    try:
        with open(filename, 'r') as f:
            return f.read()
    except FileNotFoundError:
        sys.exit(f"错误: 文件 '{filename}' 不存在")
    except PermissionError:
        sys.exit(f"错误: 没有权限读取 '{filename}'")
    except Exception as e:
        sys.exit(f"错误: {e}")

# 主程序
if __name__ == "__main__":
    if len(sys.argv) < 2:
        sys.exit("用法: python script.py <文件名>")
    
    content = process_file(sys.argv[1])
    print(f"文件内容长度: {len(content)}")

4.4 终端查看退出状态码

bash

运行

复制代码
# Linux/Mac
python script.py
echo $? 

# Windows
python script.py
echo %ERRORLEVEL%

五、标准输入输出流

Python 三大标准流,负责程序的输入、输出、错误打印。

5.1 三大标准流

表格

对象 用途 默认目标
sys.stdin 标准输入 键盘
sys.stdout 标准输出 屏幕
sys.stderr 标准错误 屏幕

5.2 sys.stdin - 读取输入

python

运行

复制代码
import sys

# 读取一行
line = sys.stdin.readline()
print(f"读取: {line}")

# 读取所有行
for line in sys.stdin:
    print(f"行: {line.strip()}")

# 读取指定字符数
data = sys.stdin.read(100)

管道输入检测

python

运行

复制代码
import sys

# 判断是否有管道输入
if not sys.stdin.isatty():
    data = sys.stdin.read()
    print(f"从管道读取 {len(data)} 字符")
else:
    print("没有管道输入,等待用户输入...")
    user_input = input("请输入: ")

5.3 sys.stdout - 输出控制

python

运行

复制代码
import sys

# 直接写入(不自动换行)
sys.stdout.write("Hello\n")

# 重定向输出到文件
original = sys.stdout
with open('output.txt', 'w') as f:
    sys.stdout = f
    print("这段内容进入文件")
    sys.stdout = original  # 恢复默认输出

print("回到屏幕输出")

5.4 sys.stderr - 错误输出

python

运行

复制代码
import sys

# 错误信息独立输出
sys.stderr.write("警告: 配置缺失\n")

# 重定向错误到日志文件
sys.stderr = open('error.log', 'w')
print("错误信息", file=sys.stderr)

5.5 同时输出到屏幕和文件

python

运行

复制代码
import sys

class Tee:
    """同时输出到多个目标"""
    def __init__(self, *files):
        self.files = files
    
    def write(self, obj):
        for f in self.files:
            f.write(obj)
    
    def flush(self):
        for f in self.files:
            f.flush()

# 同时输出到屏幕和日志文件
log_file = open('app.log', 'w')
sys.stdout = Tee(sys.stdout, log_file)

print("这条信息同时出现在屏幕和日志文件")

六、版本与平台检测

用于判断 Python 版本、操作系统,实现跨平台兼容。

6.1 Python 版本信息

python

运行

复制代码
import sys

# 完整版本字符串
print(sys.version)

# 版本元组(便于比较)
print(sys.version_info)

# 单独获取版本号
print(f"主版本: {sys.version_info.major}")
print(f"次版本: {sys.version_info.minor}")
print(f"微版本: {sys.version_info.micro}")

6.2 版本兼容性检查

python

运行

复制代码
import sys

# 检查 Python 版本
if sys.version_info < (3, 8):
    print("此脚本需要 Python 3.8+")
    sys.exit(1)

# 根据版本使用不同特性
if sys.version_info >= (3, 9):
    # Python 3.9+ 新特性
    pass
else:
    # 兼容旧版本
    pass

6.3 操作系统检测

python

运行

复制代码
import sys

platform = sys.platform

if platform == 'win32':
    print("Windows 系统")
elif platform == 'linux':
    print("Linux 系统")
elif platform == 'darwin':
    print("macOS 系统")

6.4 其他系统信息

python

运行

复制代码
import sys

# 最大整数
print(f"最大整数: {sys.maxsize}")

# 字节序
print(f"字节序: {'小端' if sys.byteorder == 'little' else '大端'}")

# 解释器路径
print(f"Python 解释器路径: {sys.executable}")

七、内存与递归控制

7.1 获取对象大小

python

运行

复制代码
import sys

# 基本类型占用字节数
print(f"整数: {sys.getsizeof(42)} 字节")
print(f"字符串: {sys.getsizeof('hello')} 字节")
print(f"列表: {sys.getsizeof([1,2,3])} 字节")

# 空对象大小
print(f"空列表: {sys.getsizeof([])} 字节")
print(f"空字典: {sys.getsizeof({})} 字节")

7.2 递归深度控制

python

运行

复制代码
import sys

# 查看当前递归限制
print(f"递归限制: {sys.getrecursionlimit()}")

# 设置新限制(谨慎使用!)
sys.setrecursionlimit(10000)

7.3 引用计数

python

运行

复制代码
import sys

a = [1, 2, 3]
b = a
c = a

# 查看引用次数(getrefcount 本身会增加一次计数)
print(f"引用计数: {sys.getrefcount(a)}")  # 输出 4

del b
print(f"删除后: {sys.getrefcount(a)}")   # 输出 3

八、异常处理

8.1 获取异常信息

python

运行

复制代码
import sys

try:
    1 / 0
except ZeroDivisionError:
    exc_type, exc_value, exc_tb = sys.exc_info()
    
    print(f"异常类型: {exc_type.__name__}")
    print(f"异常信息: {exc_value}")
    print(f"追踪信息: {exc_tb}")

8.2 自定义异常钩子

python

运行

复制代码
import sys

def custom_excepthook(exc_type, exc_value, exc_tb):
    """自定义全局异常处理"""
    print("=" * 40)
    print("程序出错了!")
    print(f"类型: {exc_type.__name__}")
    print(f"信息: {exc_value}")
    print("=" * 40)

# 设置自定义异常处理
sys.excepthook = custom_excepthook

# 测试未捕获异常
# raise ValueError("测试错误")

九、完整实战案例

案例 1:文件批量处理工具

python

运行

复制代码
#!/usr/bin/env python3
# file_batch.py - 批量文件处理工具
import sys
import os

class FileBatch:
    """批量文件处理器"""
    
    def __init__(self):
        self.verbose = False
        self.output_dir = "output"
    
    def parse_args(self):
        """解析命令行参数"""
        args = sys.argv[1:]
        
        for i, arg in enumerate(args):
            if arg in ("-v", "--verbose"):
                self.verbose = True
            elif arg in ("-o", "--output"):
                if i + 1 < len(args):
                    self.output_dir = args[i + 1]
            elif arg in ("-h", "--help"):
                self.show_help()
                sys.exit(0)
            elif not arg.startswith("-"):
                return arg
        
        return None
    
    def show_help(self):
        """显示帮助信息"""
        print("""
批量文件处理工具 v1.0

用法: python file_batch.py [选项] <输入>

选项:
  -v, --verbose     显示详细信息
  -o, --output DIR  输出目录 (默认: output)
  -h, --help        显示帮助

示例:
  python file_batch.py data.txt
  python file_batch.py -v -o results data.txt
        """)
    
    def process_file(self, filepath):
        """处理单个文件"""
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                content = f.read()
            
            lines = len(content.split('\n'))
            os.makedirs(self.output_dir, exist_ok=True)
            
            basename = os.path.basename(filepath)
            output_path = os.path.join(self.output_dir, f"processed_{basename}")
            
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(f"原文件: {filepath}\n")
                f.write(f"行数: {lines}\n")
                f.write(f"字符数: {len(content)}\n")
            
            return lines
            
        except FileNotFoundError:
            sys.stderr.write(f"错误: 文件不存在 - {filepath}\n")
            return None
        except PermissionError:
            sys.stderr.write(f"错误: 权限不足 - {filepath}\n")
            return None
        except Exception as e:
            sys.stderr.write(f"错误: {e}\n")
            return None
    
    def run(self):
        """主运行方法"""
        try:
            input_path = self.parse_args()
            
            if not input_path:
                sys.stderr.write("错误: 请指定输入文件\n")
                self.show_help()
                sys.exit(1)
            
            if self.verbose:
                sys.stderr.write(f"[详细] 输入: {input_path}\n")
                sys.stderr.write(f"[详细] 输出目录: {self.output_dir}\n")
            
            if os.path.isfile(input_path):
                result = self.process_file(input_path)
                if result is not None:
                    print(f"处理完成: {input_path} -> {result} 行")
            else:
                sys.stderr.write(f"错误: 无效输入 - {input_path}\n")
                sys.exit(1)
            
        except KeyboardInterrupt:
            sys.stderr.write("\n用户中断\n")
            sys.exit(130)
        except Exception as e:
            sys.stderr.write(f"未处理异常: {e}\n")
            sys.exit(1)

if __name__ == "__main__":
    app = FileBatch()
    app.run()

案例 2:管道数据处理

python

运行

复制代码
#!/usr/bin/env python3
# pipe_processor.py - 管道数据处理
import sys
import json

def process_line(line):
    """处理单行数据"""
    line = line.strip()
    if not line:
        return None
    
    return {
        "original": line,
        "length": len(line),
        "words": len(line.split())
    }

def main():
    results = []
    
    if sys.stdin.isatty():
        print("请输入数据(Ctrl+D 结束):")
        lines = sys.stdin.readlines()
    else:
        lines = sys.stdin.readlines()
    
    for line in lines:
        result = process_line(line)
        if result:
            results.append(result)
    
    if results:
        print(json.dumps(results, ensure_ascii=False, indent=2))
        sys.stderr.write(f"处理完成: {len(results)} 条记录\n")
    else:
        sys.stderr.write("警告: 没有有效数据\n")
        sys.exit(1)

if __name__ == "__main__":
    main()

案例 3:环境检测工具

python

运行

复制代码
#!/usr/bin/env python3
# env_check.py - 环境检测工具
import sys

def check_environment():
    """检查运行环境"""
    checks = []
    
    py_ok = sys.version_info >= (3, 7)
    checks.append(("Python >= 3.7", py_ok))
    
    platform_ok = sys.platform in ['linux', 'darwin', 'win32']
    checks.append(("平台支持", platform_ok))
    
    print("=" * 40)
    print("环境检测报告")
    print("=" * 40)
    print(f"Python版本: {sys.version_info.major}.{sys.version_info.minor}")
    print(f"平台: {sys.platform}")
    print(f"解释器路径: {sys.executable}")
    print("\n检测项:")
    
    all_ok = True
    for name, ok in checks:
        status = "✓" if ok else "✗"
        print(f"  [{status}] {name}")
        if not ok:
            all_ok = False
    
    print("=" * 40)
    
    if all_ok:
        print("环境检查通过")
        return 0
    else:
        print("环境检查失败")
        return 1

if __name__ == "__main__":
    sys.exit(check_environment())

十、常见问题与避坑

10.1 五大常见坑点

表格

坑点 说明 解决方案
argv 类型问题 所有参数都是字符串 数字必须用 int()/float() 转换
path 修改不持久 仅当前进程生效 设置环境变量 PYTHONPATH
重定向忘记恢复 输出丢失 / 异常 先保存原始对象,用完立即恢复
多线程输出混乱 打印内容交错 使用 logging 模块
递归过深 栈溢出崩溃 优先用迭代替代深度递归

10.2 最佳实践

python

运行

复制代码
import sys

# 安全获取命令行参数
def safe_get_arg(index, default=None):
    return sys.argv[index] if len(sys.argv) > index else default

# 上下文管理器管理输出重定向
class Redirect:
    def __init__(self, target):
        self.target = target
        self.original = sys.stdout
    
    def __enter__(self):
        sys.stdout = self.target
        return self
    
    def __exit__(self, *args):
        sys.stdout = self.original

# 使用示例
with open('out.txt', 'w') as f:
    with Redirect(f):
        print("这段内容写入文件")
print("恢复屏幕输出")

十一、速查表

11.1 常用属性速查

表格

属性 用途 示例
sys.argv 命令行参数 args = sys.argv[1:]
sys.path 模块搜索路径 sys.path.append('./lib')
sys.version Python 版本 print(sys.version)
sys.platform 操作系统 if sys.platform == 'win32'
sys.maxsize 最大整数 max_val = sys.maxsize

11.2 常用方法速查

表格

方法 用途 示例
sys.exit() 退出程序 sys.exit(1)
sys.getsizeof() 获取对象大小 size = sys.getsizeof(obj)
sys.getrecursionlimit() 获取递归限制 limit = sys.getrecursionlimit()
sys.exc_info() 获取异常信息 type, value, tb = sys.exc_info()

11.3 标准流速查

表格

对象 常用操作 示例
sys.stdin 读取输入 data = sys.stdin.read()
sys.stdout 标准输出 sys.stdout.write('text')
sys.stderr 错误输出 sys.stderr.write('error')

十二、总结

核心要点

sys 模块是 Python 最基础的系统交互接口,掌握它能让你的脚本:

  • ✅ 更灵活:通过命令行参数控制行为
  • ✅ 更专业:使用标准退出状态码
  • ✅ 更健壮:完善的错误处理和环境检测
  • ✅ 更实用:支持管道数据处理、输出重定向

学习路径

  • 入门 :掌握 argvexit()stdout
  • 进阶 :学会 path 管理、环境检测
  • 精通:异常钩子、内存分析、自定义重定向

一句话总结

sys = 脚本与 Python 解释器的桥梁,是每个 Python 程序员的必修课

相关推荐
瑶总迷弟2 小时前
Python入门第6章:字典(键值对数据结构)
java·数据结构·python
第一程序员2 小时前
Python游戏开发:从入门到实践
python·github
Yao.Li3 小时前
Dify 本地环境忘记登录密码问题排障文档
人工智能·python
_MyFavorite_3 小时前
JAVA重点基础、进阶知识及易错点总结(14)字节流 & 字符流
java·开发语言·python
Eric.Lee20213 小时前
python实现pdf转图片png
linux·python·pdf
deep_drink3 小时前
1.2、Python 与编程基础:文件处理与常用库
开发语言·python·elasticsearch·llm
Hello.Reader3 小时前
一堆 `.ts` 分片合并后音画不同步?从问题定位到通用修复脚本的完整实战
python·ffmpeg·视频
好家伙VCC3 小时前
**CQRS模式实战:用Go语言构建高并发读写分离架构**在现代分布式系统中,随着业务复杂度的提升和用户量的增长,传统的单数据库模型逐
java·数据库·python·架构·golang
fy121633 小时前
Java进阶——IO 流
java·开发语言·python