sys模块
sys 模块提供了与 Python 解释器和系统环境交互的接口。它包含命令行参数、路径配置、标准输入输出、解释器信息等功能,是编写脚本和工具时最常用的模块之一。
命令行参数
sys.argv 是一个列表,包含命令行传入的所有参数:
import sys
print sys.argv
运行 python script.py arg1 arg2:
['script.py', 'arg1', 'arg2']
sys.argv[0]是脚本名sys.argv[1:]是用户传入的参数
实际应用:
import sys
def main():
if len(sys.argv) < 2:
print "Usage: python script.py <filename>"
sys.exit(1)
filename = sys.argv[1]
with open(filename, "r") as f:
print f.read()
if __name__ == "__main__":
main()
退出程序
sys.exit() 终止程序并返回状态码:
import sys
sys.exit(0) # 正常退出
sys.exit(1) # 异常退出(非零表示错误)
sys.exit("Error message") # 退出并打印消息
sys.exit() 抛出 SystemExit 异常,可以被捕获:
try:
sys.exit(1)
except SystemExit as e:
print "Exit code:", e.code
路径配置
sys.path 是模块搜索路径列表:
import sys
print sys.path
# ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', ...]
- 第一个空字符串表示当前目录
- 可以动态添加路径:
sys.path.insert(0, "/path/to/my/modules")
import my_module
注意:修改 sys.path 只在当前进程有效。更好的做法是通过 PYTHONPATH 环境变量或 .pth 文件配置。
标准输入输出
import sys
print sys.stdin # <open file '<stdin>', mode 'r'>
print sys.stdout # <open file '<stdout>', mode 'w'>
print sys.stderr # <open file '<stderr>', mode 'w'>
重定向输出:
# 写入文件
sys.stdout = open("output.txt", "w")
print "This goes to file"
sys.stdout = sys.__stdout__ # 恢复
打印错误信息:
import sys
print >>sys.stderr, "Error: something went wrong"
>> 语法将输出重定向到指定文件对象。错误信息应该输出到 stderr,这样用户可以通过 shell 重定向分离正常输出和错误:
python script.py > output.log 2> error.log
解释器信息
import sys
print sys.version # Python 版本信息
print sys.version_info # (2, 7, 18, 'final', 0) —— 版本号元组
print sys.platform # 'linux2', 'win32', 'darwin'
print sys.maxint # 2147483647(32位)或更大(64位)
print sys.maxsize # 最大列表/字符串大小
print sys.getsizeof(1) # 对象内存占用(字节)
版本检查:
import sys
if sys.version_info < (2, 7):
print "Python 2.7+ required"
sys.exit(1)
模块信息
import sys
print sys.modules # 已加载模块的字典
print "os" in sys.modules # True
print sys.getrefcount("hello") # 对象的引用计数
递归限制
import sys
print sys.getrecursionlimit() # 默认 1000
sys.setrecursionlimit(2000) # 设置递归深度限制
防止无限递归导致栈溢出。注意:设置过高可能导致 C 栈溢出,程序崩溃。
实际应用
跨平台换行符:
import sys
if sys.platform == "win32":
newline = "\r\n"
elif sys.platform == "darwin":
newline = "\r"
else:
newline = "\n"
实际上,os.linesep 已经提供了这个值,但 sys.platform 在需要更细粒度判断时有用。
脚本路径处理:
import sys
import os
# 获取脚本所在目录
script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
config_path = os.path.join(script_dir, "config.ini")
处理管道输入:
import sys
if not sys.stdin.isatty():
# 从管道读取
for line in sys.stdin:
process(line)
else:
# 交互式运行
data = raw_input("Enter data: ")
process(data)
sys 与 os 的选择
| 需求 | 推荐模块 |
|---|---|
| 文件路径操作 | os.path |
| 环境变量 | os.environ |
| 命令行参数 | sys.argv |
| 退出程序 | sys.exit() |
| 标准输入输出 | sys.stdin/stdout/stderr |
| 模块路径 | sys.path |
| 版本信息 | sys.version_info |