目录
2. 控制标准输入/输出流:sys.stdin, sys.stdout, sys.stderr
(1)sys.version 和 sys.version_info
6. 获取最大递归深度:sys.getrecursionlimit()
前言
在 Python 的标准库中,sys
模块(全称 system)是一个非常基础且强大的模块,它提供了许多与 Python 解释器交互的功能。无论你是开发命令行工具、进行系统调试,还是希望控制程序运行环境,sys
模块都扮演着至关重要的角色。
本文将带你深入了解 sys
模块的主要功能及其常见使用场景,并提供丰富的示例和解释,帮助你全面掌握这个核心模块。
一、什么是 sys 模块?
sys
是 "system" 的缩写,是 Python 内置的一个核心模块,无需额外安装即可直接导入使用。它主要用于访问解释器相关的变量和函数,能够与当前运行的 Python 环境进行低层次交互。
要使用它,只需简单导入:
import sys
二、常用功能详解
1. 获取命令行参数:sys.argv
当你通过命令行执行一个 Python 脚本时,可以通过 sys.argv
来获取传递给脚本的参数。
示例:
import sys
print("脚本名称:", sys.argv[0])
print("参数列表:", sys.argv[1:])
运行:
python script.py arg1 arg2
输出:
脚本名称: script.py
参数列表: ['arg1', 'arg2']
这是构建命令行工具的基础功能之一。
更复杂的用法
我们可以利用 sys.argv
编写一个简单的加法器:
import sys
if len(sys.argv) < 3:
print("请传入两个数字作为参数!")
else:
try:
a = int(sys.argv[1])
b = int(sys.argv[2])
print(f"{a} + {b} = {a + b}")
except ValueError:
print("请输入有效的整数!")
运行:
python adder.py 5 8
输出:
5 + 8 = 13
2. 控制标准输入/输出流:sys.stdin
, sys.stdout
, sys.stderr
这三个对象分别代表标准输入、标准输出和标准错误流。
-
读取输入:
import sys print("请输入内容(Ctrl+D 结束):") lines = sys.stdin.read() print("你输入的内容为:") print(lines)
-
重定向输出:
可以临时修改
sys.stdout
或sys.stderr
来捕获或重定向输出:import sys # 将标准输出重定向到文件 with open('output.txt', 'w') as f: sys.stdout = f print("这行文字会被写入 output.txt 文件中。") # 恢复标准输出 sys.stdout = sys.__stdout__
示例:日志记录器
我们也可以创建一个简单的日志记录器,把所有打印信息保存到日志文件中:
import sys
from datetime import datetime
class Logger:
def __init__(self, filename):
self.terminal = sys.stdout
self.log = open(filename, "w")
def write(self, message):
self.terminal.write(message)
self.log.write(f"[{datetime.now()}] {message}")
def flush(self):
pass
sys.stdout = Logger("logfile.txt")
print("Hello, this is a log message.")
运行后,终端会显示输出,同时也会写入 logfile.txt
文件中。
3. 获取 Python 解释器信息
(1)sys.version
和 sys.version_info
显示当前 Python 版本信息:
import sys
print("Python 版本字符串:", sys.version)
print("版本元组:", sys.version_info)
输出示例(根据实际版本不同而异):
Python 版本字符串: 3.9.7 (default, Sep 16 2021, 13:09:58)
[GCC 7.5.0]
版本元组: sys.version_info(major=3, minor=9, micro=7, releaselevel='final', serial=0)
(2)sys.platform
返回当前操作系统平台标识符:
print("平台标识:", sys.platform)
可能的输出包括:
'win32'
(Windows)'darwin'
(macOS)'linux'
(Linux)
这对跨平台兼容性处理非常有用。
示例:跨平台路径拼接
import sys
import os
def cross_platform_path(*args):
if sys.platform == 'win32':
return '\\'.join(args)
else:
return '/'.join(args)
print(cross_platform_path("home", "user", "file.txt"))
4. 控制模块搜索路径:sys.path
sys.path
是一个列表,表示 Python 在导入模块时查找的路径顺序。你可以动态添加目录,以便让解释器找到自定义模块。
import sys
sys.path.append('/path/to/my/modules')
此外,还可以查看当前路径设置:
for path in sys.path:
print(path)
示例:加载本地模块
假设你有一个模块 mymodule.py
放在 /home/user/modules/
目录下:
import sys
sys.path.append("/home/user/modules/")
import mymodule
mymodule.hello()
5. 终止程序:sys.exit()
退出当前 Python 程序,可以传入退出状态码:
import sys
print("程序开始运行...")
sys.exit(0) # 正常退出
# sys.exit(1) 表示异常退出
通常用于在条件不满足时提前终止程序。
示例:验证用户权限
import sys
def check_permission(user):
allowed_users = ["admin", "developer"]
if user not in allowed_users:
print("权限不足,程序退出。")
sys.exit(1)
check_permission("guest")
6. 获取最大递归深度:sys.getrecursionlimit()
Python 默认限制了递归的最大深度,防止栈溢出:
import sys
print("最大递归深度:", sys.getrecursionlimit())
默认值通常是 1000。也可以通过 sys.setrecursionlimit(n)
设置新的递归深度(不建议随意更改)。
示例:测试递归极限
import sys
def recurse(n):
print(n)
recurse(n + 1)
try:
recurse(1)
except RecursionError:
print("达到递归深度限制!")
三、高级用途
1. 获取当前调用栈:sys._getframe()
可用于调试目的,获取当前函数调用栈帧信息:
import sys
def show_caller():
frame = sys._getframe(1) # 获取上一级调用者的信息
print(f"被 {frame.f_code.co_name} 调用")
def test():
show_caller()
test()
输出:
被 test 调用
注意:_getframe()
是带下划线的私有方法,一般用于调试,不推荐用于生产代码。
2. 获取正在运行的模块:sys.modules
这是一个字典,保存了所有已加载的模块。可以用来检查某个模块是否已经被导入。
import sys
print(sys.modules.keys()) # 查看所有已加载模块
四、实战案例:构建一个简易命令行解析器
结合 sys.argv
、sys.stdin
、sys.stdout
,我们可以编写一个完整的命令行工具。
import sys
def help():
print("Usage: python cli_tool.py [command] [options]")
print("Available commands:")
print(" echo <text> - Prints the given text")
print(" read - Reads input from stdin and prints it")
print(" exit - Exits the program")
def main():
if len(sys.argv) < 2:
help()
return
command = sys.argv[1]
if command == "echo":
if len(sys.argv) > 2:
print(" ".join(sys.argv[2:]))
else:
print("Please provide text to echo.")
elif command == "read":
print("请输入内容(Ctrl+D 结束):")
lines = sys.stdin.read()
print("你输入的内容为:")
print(lines)
elif command == "exit":
print("Exiting...")
sys.exit(0)
else:
print(f"Unknown command: {command}")
help()
if __name__ == "__main__":
main()