大家好,我是唐叔!上期我们聊了os模块的基础操作。今天唐叔想带大家看看os模块更骚的操作,保证让你直呼"原来还能这样!"
文章目录
一、环境变量操控术
import os
# 获取所有环境变量(字典形式)
env_vars = os.environ
print(env_vars['PATH']) # 查看系统PATH
# 设置临时环境变量(仅当前进程有效)
os.environ['MY_APP_MODE'] = 'DEBUG'
# 安全获取环境变量(避免KeyError)
db_host = os.getenv('DB_HOST', 'localhost') # 第二个参数是默认值
唐叔点评:环境变量是配置管理的银弹,特别是在容器化部署时。但记住:通过os.environ
设置的变量只在当前进程有效,不会真正修改系统环境!
二、进程控制黑魔法
import os
# 获取当前进程ID
print(f"我的PID是:{os.getpid()}")
# 获取父进程ID(在Linux/Mac下有用)
print(f"父进程PID是:{os.getppid()}")
# 终止进程(危险操作!)
os._exit(1) # 立即终止,连finally都不会执行
真实案例:我曾经用os.getpid()
实现过多进程日志追踪,每个进程在日志中标记自己的PID,调试分布式系统时简直不要太爽!
三、文件描述符操作
# 低级文件操作(直接操作文件描述符)
fd = os.open('data.bin', os.O_RDWR | os.O_CREAT) # 读写模式打开,不存在则创建
os.write(fd, b'Binary data') # 写入字节数据
os.lseek(fd, 0, os.SEEK_SET) # 移动指针到文件开头
data = os.read(fd, 100) # 读取100字节
os.close(fd)
性能对比:在百万级小文件读写测试中,这种底层操作比普通open()
快15%-20%,但代价是代码更复杂。唐叔建议:除非真有性能瓶颈,否则慎用!
四、终端操控技巧
# 获取终端尺寸
rows, cols = os.get_terminal_size()
print(f"终端:{cols}列 × {rows}行")
# 清屏(跨平台版)
os.system('cls' if os.name == 'nt' else 'clear')
# 执行命令并获取输出(Python 3.7+)
result = os.popen('ls -l').read()
唐叔小技巧:os.get_terminal_size()
特别适合做CLI工具时动态调整输出格式,比如进度条宽度自适应终端!
五、用户权限管理
# 获取当前登录用户(跨平台)
import getpass
print(getpass.getuser()) # 比os.getlogin()更可靠
# 检查文件权限
print("可读?", os.access('data.txt', os.R_OK))
print("可写?", os.access('data.txt', os.W_OK))
print("可执行?", os.access('script.sh', os.X_OK))
# 修改文件权限(Linux/Mac)
os.chmod('script.sh', 0o755) # 八进制表示法
避坑指南:Windows下权限系统完全不同,os.chmod()
只能设置只读属性,完整权限管理需要win32api
模块。
六、高级路径处理
# 解析路径中的波浪号(~)
expanded_path = os.path.expanduser('~/projects')
# 环境变量展开(支持${VAR}格式)
config_path = os.path.expandvars('${APPDATA}/config.ini')
# 获取文件真实路径(解析符号链接)
real_path = os.path.realpath('/usr/bin/python3')
# 判断是否是绝对路径(跨平台正确判断)
print(os.path.isabs('../test')) # False
冷知识:os.path.realpath()
不仅能解析符号链接,还会自动处理..
和.
的相对路径引用!
七、临时文件妙用
import tempfile
# 创建临时文件(自动删除)
with tempfile.NamedTemporaryFile(delete=True) as tmp:
tmp.write(b'临时数据')
tmp.seek(0)
print(tmp.read())
# 创建临时目录
with tempfile.TemporaryDirectory() as tmpdir:
print(f"临时目录:{tmpdir}")
# 目录会在with块结束后自动删除
唐叔经验:测试代码中尽量用临时文件,既不用手动清理,还能避免多个测试用例相互干扰。
八、文件锁机制
import fcntl # Unix系统专用
with open('data.txt', 'r+') as f:
# 加排他锁
fcntl.flock(f, fcntl.LOCK_EX)
# 临界区操作
f.write('独占写入')
# 锁会自动释放
Windows替代方案:可以用msvcrt.locking()
,但更推荐用portalocker
第三方库实现跨平台文件锁。
九、递归文件统计(进阶版)
def get_dir_stats(path):
"""统计目录大小及文件类型分布"""
stats = {'total_size': 0, 'file_types': {}}
for root, _, files in os.walk(path):
for file in files:
fp = os.path.join(root, file)
stats['total_size'] += os.path.getsize(fp)
# 按扩展名分类
ext = os.path.splitext(file)[1].lower()
stats['file_types'][ext] = stats['file_types'].get(ext, 0) + 1
return stats
print(get_dir_stats('/path/to/project'))
输出示例:
{
'total_size': 1523421,
'file_types': {'.py': 12, '.txt': 5, '.jpg': 3}
}
十、跨平台隐藏文件
# 隐藏文件(Windows)
if os.name == 'nt':
import ctypes
ctypes.windll.kernel32.SetFileAttributesW('secret.txt', 2)
# Unix系统隐藏文件(文件名以点开头)
os.rename('secret.txt', '.secret.txt')
终极实战:智能文件分类器
import os
import shutil
def file_sorter(source_dir, target_dir):
"""根据扩展名自动分类文件"""
if not os.path.exists(target_dir):
os.makedirs(target_dir)
for item in os.listdir(source_dir):
src_path = os.path.join(source_dir, item)
if os.path.isfile(src_path):
ext = os.path.splitext(item)[1][1:] # 去掉点
dest_dir = os.path.join(target_dir, ext.upper() + '_FILES')
os.makedirs(dest_dir, exist_ok=True)
shutil.move(src_path, os.path.join(dest_dir, item))
print(f"Moved {item} to {dest_dir}")
# 使用示例
file_sorter('~/Downloads', '~/SortedFiles')
功能亮点:
- 自动按扩展名创建分类文件夹(如PDF_FILES)
- 处理已存在目录的情况
- 显示详细操作日志
结语
os模块就像Python标准库里的"多功能军刀",今天介绍的这些操作可能你平时用不到,但关键时刻绝对能救命。记住唐叔的话:
高级程序员和初学者的区别,不在于知道多少语法,而在于知道多少"隐藏API"
我是唐叔,如果觉得有用,别忘了三连支持!