Python `os` / `sys` / `shutil` 模块:系统级操作的极限运用

各位观众,各位朋友,各位程序员,大家好!

今天咱们来聊聊Python里那些“搞系统”的模块:ossysshutil。这仨哥们儿,那是Python与操作系统打交道的三板斧,玩儿明白了,你的Python脚本就能上天入地,呼风唤雨(当然,是在你的电脑里)。

别害怕,虽然听起来“系统级”很高大上,其实用起来一点都不难。咱们争取用最接地气的方式,把这几个模块的功能掰开了揉碎了,讲清楚、说明白。

第一板斧:os 模块 – “操作系统,我来了!”

os 模块,可以说是Python和操作系统之间的桥梁。有了它,你的Python代码就能执行一些操作系统级别的操作,比如创建文件夹、删除文件、获取环境变量等等。

1. 路径操作:不怕迷路,指哪打哪!

在文件系统中,路径就像地图上的坐标,指引我们找到目标文件或文件夹。os.path 子模块就是专门用来处理路径的。

  • os.path.join():路径拼接,妈妈再也不用担心我写错斜杠了!

    以前拼接路径,手动加斜杠,一不小心就出错。有了os.path.join(),就方便多了,它会根据操作系统自动选择正确的路径分隔符。

    import os
    
    # 假设我们要创建 'logs/2023-10-27/app.log' 这样的路径
    path = os.path.join('logs', '2023-10-27', 'app.log')
    print(path)  # 输出:logs/2023-10-27/app.log (在Linux/macOS上)
    # 或者 logs2023-10-27app.log (在Windows上)
    
    # 还可以拼接绝对路径
    abs_path = os.path.join('/home/user', 'documents', 'report.pdf') #Linux
    print(abs_path)
    abs_path = os.path.join('C:\Users\user', 'documents', 'report.pdf') #windows
    print(abs_path)
  • os.path.exists():确认过眼神,是个真实存在的路径!

    在操作文件之前,先确认一下路径是否存在是个好习惯。

    import os
    
    path = 'logs/2023-10-27/app.log'
    if os.path.exists(path):
        print(f"路径 '{path}' 存在")
    else:
        print(f"路径 '{path}' 不存在")
  • os.path.isfile()os.path.isdir():你是文件?还是文件夹?

    有时候我们需要区分路径指向的是文件还是文件夹。

    import os
    
    path = 'my_file.txt' # 创建一个文件
    with open(path, 'w') as f:
        f.write("Hello, world!")
    
    if os.path.isfile(path):
        print(f"'{path}' 是一个文件")
    elif os.path.isdir(path):
        print(f"'{path}' 是一个目录")
    else:
        print(f"'{path}' 既不是文件也不是目录")
    os.remove(path) # 删除文件,清理现场
  • os.path.abspath():给我你的绝对路径!

    将相对路径转换为绝对路径,方便后续操作。

    import os
    
    relative_path = 'my_file.txt'
    absolute_path = os.path.abspath(relative_path)
    print(f"'{relative_path}' 的绝对路径是: {absolute_path}")
  • os.path.dirname()os.path.basename():拆分路径,各取所需!

    os.path.dirname() 获取路径的目录部分,os.path.basename() 获取路径的文件名部分。

    import os
    
    path = '/home/user/documents/report.pdf'
    directory = os.path.dirname(path)
    filename = os.path.basename(path)
    
    print(f"目录: {directory}")  # 输出: /home/user/documents
    print(f"文件名: {filename}")  # 输出: report.pdf
  • os.path.splitext():分离文件名和扩展名,强迫症患者福音!

    将文件名和扩展名分开。

    import os
    
    filename = 'image.png'
    name, ext = os.path.splitext(filename)
    
    print(f"文件名: {name}")  # 输出: image
    print(f"扩展名: {ext}")  # 输出: .png

2. 文件和目录操作:增删改查,样样精通!

  • os.mkdir()os.makedirs():创建文件夹,单层 or 多层?

    os.mkdir() 创建单层目录,如果父目录不存在会报错。os.makedirs() 可以创建多层目录,即使父目录不存在也没关系。

    import os
    
    # 创建单层目录
    try:
        os.mkdir('my_directory')
        print("单层目录 'my_directory' 创建成功")
    except FileExistsError:
        print("单层目录 'my_directory' 已经存在")
    
    # 创建多层目录
    try:
        os.makedirs('parent/child/grandchild')
        print("多层目录 'parent/child/grandchild' 创建成功")
    except FileExistsError:
        print("多层目录 'parent/child/grandchild' 已经存在")
    
    # 清理现场
    os.rmdir('my_directory')
    os.removedirs('parent/child/grandchild') #只能删除空目录
  • os.rmdir()os.removedirs():删除空文件夹,用完就丢!

    os.rmdir() 删除单层空目录,os.removedirs() 删除多层空目录。注意,只能删除空目录!

    import os
    
    # 创建一个空目录
    os.mkdir('empty_directory')
    
    # 删除空目录
    os.rmdir('empty_directory')
    print("空目录 'empty_directory' 删除成功")
  • os.remove():删除文件,一刀两断!

    删除指定的文件。

    import os
    
    # 创建一个文件
    with open('my_file.txt', 'w') as f:
        f.write("Hello, world!")
    
    # 删除文件
    os.remove('my_file.txt')
    print("文件 'my_file.txt' 删除成功")
  • os.rename()os.renames():重命名文件或文件夹,改头换面!

    os.rename() 重命名文件或文件夹,os.renames() 可以重命名多层目录。

    import os
    
    # 创建一个文件
    with open('old_name.txt', 'w') as f:
        f.write("Hello, world!")
    
    # 重命名文件
    os.rename('old_name.txt', 'new_name.txt')
    print("文件 'old_name.txt' 重命名为 'new_name.txt' 成功")
    
    # 清理现场
    os.remove('new_name.txt')
  • os.listdir():列出目录下的文件和文件夹,一览无余!

    获取指定目录下所有文件和文件夹的名称列表。

    import os
    
    # 创建一些文件和目录
    os.makedirs('my_directory/subdir')
    with open('my_directory/file1.txt', 'w') as f:
        f.write("File 1")
    with open('my_directory/file2.txt', 'w') as f:
        f.write("File 2")
    
    # 列出目录下的文件和文件夹
    files = os.listdir('my_directory')
    print(f"'my_directory' 下的文件和文件夹: {files}")  # 输出: ['subdir', 'file1.txt', 'file2.txt']
    
    # 清理现场
    os.remove('my_directory/file1.txt')
    os.remove('my_directory/file2.txt')
    os.rmdir('my_directory/subdir')
    os.rmdir('my_directory')
  • os.walk():遍历目录树,地毯式搜索!

    os.walk() 可以遍历目录树,返回一个生成器,每次迭代返回一个三元组 (dirpath, dirnames, filenames),分别表示当前目录的路径、当前目录下的子目录名列表和当前目录下的文件名列表。

    import os
    
    # 创建一个目录树
    os.makedirs('my_directory/subdir1')
    os.makedirs('my_directory/subdir2')
    with open('my_directory/file1.txt', 'w') as f:
        f.write("File 1")
    with open('my_directory/subdir1/file2.txt', 'w') as f:
        f.write("File 2")
    
    # 遍历目录树
    for dirpath, dirnames, filenames in os.walk('my_directory'):
        print(f"当前目录: {dirpath}")
        print(f"子目录: {dirnames}")
        print(f"文件: {filenames}")
        print("---")
    
    # 清理现场
    os.remove('my_directory/file1.txt')
    os.remove('my_directory/subdir1/file2.txt')
    os.rmdir('my_directory/subdir1')
    os.rmdir('my_directory/subdir2')
    os.rmdir('my_directory')

3. 环境变量:窥探系统的秘密!

  • os.environ:访问环境变量,获取系统信息!

    os.environ 是一个字典,包含了系统的环境变量。

    import os
    
    # 获取环境变量
    username = os.environ.get('USERNAME') #windows
    username = os.environ.get('USER') #Linux
    print(f"当前用户名: {username}")
  • os.getenv():安全地获取环境变量,不怕 KeyError!

    os.getenv() 类似于 os.environ.get(),但是如果环境变量不存在,不会抛出 KeyError 异常,而是返回 None(或者你指定的默认值)。

    import os
    
    # 获取环境变量,如果不存在则返回默认值
    api_key = os.getenv('API_KEY', 'default_key')
    print(f"API Key: {api_key}")

4. 其他常用函数:

  • os.getcwd():获取当前工作目录,我在哪儿?

    import os
    
    current_directory = os.getcwd()
    print(f"当前工作目录: {current_directory}")
  • os.chdir():改变当前工作目录,换个地方!

    import os
    
    print(f"当前工作目录: {os.getcwd()}")
    os.chdir('/tmp') #需要权限
    print(f"当前工作目录: {os.getcwd()}")
    os.chdir(os.path.dirname(__file__)) # 切换回文件所在目录

第二板斧:sys 模块 – “Python 解释器,听我指挥!”

sys 模块提供对Python解释器使用或维护的一些变量的访问,以及与解释器强烈交互的函数。简单来说,就是让你控制Python解释器的一些行为。

1. 命令行参数:脚本的入口!

  • sys.argv:获取命令行参数,脚本的指令!

    sys.argv 是一个列表,包含了命令行参数。sys.argv[0] 是脚本的名称,后面的元素是传递给脚本的参数。

    import sys
    
    print(f"脚本名称: {sys.argv[0]}")
    print(f"命令行参数: {sys.argv[1:]}")
    
    # 例如,如果运行 `python my_script.py arg1 arg2 arg3`
    # 输出:
    # 脚本名称: my_script.py
    # 命令行参数: ['arg1', 'arg2', 'arg3']

2. 模块搜索路径:告诉 Python 去哪儿找模块!

  • sys.path:模块搜索路径,Python 的寻宝图!

    sys.path 是一个列表,包含了 Python 解释器搜索模块的路径。你可以修改 sys.path 来添加自定义的模块搜索路径。

    import sys
    
    print(f"模块搜索路径: {sys.path}")
    
    # 添加自定义模块搜索路径
    sys.path.append('/path/to/my/modules')
    print(f"修改后的模块搜索路径: {sys.path}")

3. 标准输入输出:与用户互动!

  • sys.stdinsys.stdoutsys.stderr:标准输入、标准输出和标准错误,Python 的嘴巴和耳朵!

    sys.stdin 用于读取标准输入,sys.stdout 用于写入标准输出,sys.stderr 用于写入标准错误。

    import sys
    
    # 从标准输入读取一行
    line = sys.stdin.readline().strip()
    print(f"你输入的是: {line}")
    
    # 向标准输出写入
    sys.stdout.write("Hello, world!n")
    
    # 向标准错误写入
    sys.stderr.write("发生了错误!n")

4. 退出程序:优雅地谢幕!

  • sys.exit():退出程序,挥手告别!

    sys.exit() 用于退出程序,可以指定退出状态码。

    import sys
    
    print("程序开始执行")
    
    # 退出程序,状态码为 0 (表示成功)
    sys.exit(0)
    
    print("这行代码不会被执行")

5. 其他常用函数:

  • sys.platform:获取操作系统平台,你是谁?

    import sys
    
    platform = sys.platform
    print(f"操作系统平台: {platform}") # win32, linux2, darwin
  • sys.version:获取 Python 版本信息,你是哪个版本?

    import sys
    
    version = sys.version
    print(f"Python 版本: {version}")

第三板斧:shutil 模块 – “文件操作,更上一层楼!”

shutil 模块提供了一系列高级的文件操作,比如复制文件、移动文件、删除目录树等等。可以看作是 os 模块的增强版。

1. 文件复制:复制粘贴,一键搞定!

  • shutil.copy():复制文件,原封不动!

    复制文件,保留权限等元数据。

    import shutil
    
    # 创建一个文件
    with open('source.txt', 'w') as f:
        f.write("This is the source file.")
    
    # 复制文件
    shutil.copy('source.txt', 'destination.txt')
    print("文件 'source.txt' 复制到 'destination.txt' 成功")
    
    # 清理现场
    os.remove('source.txt')
    os.remove('destination.txt')
  • shutil.copy2():复制文件,连时间戳也复制!

    复制文件,保留所有元数据,包括时间戳。

    import shutil
    import time
    import os
    
    # 创建一个文件
    with open('source.txt', 'w') as f:
        f.write("This is the source file.")
    #修改时间戳
    os.utime('source.txt', (time.time(), time.time())) #模拟修改时间
    
    # 复制文件
    shutil.copy2('source.txt', 'destination.txt')
    print("文件 'source.txt' 复制到 'destination.txt' 成功 (包括时间戳)")
    
    # 清理现场
    os.remove('source.txt')
    os.remove('destination.txt')
  • shutil.copyfile():复制文件内容,简单粗暴!

    只复制文件内容,不保留元数据。

    import shutil
    
    # 创建一个文件
    with open('source.txt', 'w') as f:
        f.write("This is the source file.")
    
    # 复制文件内容
    shutil.copyfile('source.txt', 'destination.txt')
    print("文件 'source.txt' 的内容复制到 'destination.txt' 成功")
    
    # 清理现场
    os.remove('source.txt')
    os.remove('destination.txt')

2. 文件移动:乾坤大挪移!

  • shutil.move():移动文件或目录,改名搬家!

    移动文件或目录到另一个位置,也可以用于重命名文件或目录。

    import shutil
    import os
    
    # 创建一个文件
    with open('source.txt', 'w') as f:
        f.write("This is the source file.")
    
    # 移动文件
    shutil.move('source.txt', 'destination.txt')
    print("文件 'source.txt' 移动到 'destination.txt' 成功")
    
    # 重命名文件
    shutil.move('destination.txt', 'new_name.txt')
    print("文件 'destination.txt' 重命名为 'new_name.txt' 成功")
    
    # 清理现场
    os.remove('new_name.txt')

3. 目录操作:复制、删除、压缩,样样精通!

  • shutil.copytree():复制目录树,克隆大法!

    复制整个目录树,包括所有文件和子目录。

    import shutil
    import os
    
    # 创建一个目录树
    os.makedirs('source_directory/subdir')
    with open('source_directory/file1.txt', 'w') as f:
        f.write("File 1")
    with open('source_directory/subdir/file2.txt', 'w') as f:
        f.write("File 2")
    
    # 复制目录树
    shutil.copytree('source_directory', 'destination_directory')
    print("目录树 'source_directory' 复制到 'destination_directory' 成功")
    
    # 清理现场
    shutil.rmtree('source_directory')
    shutil.rmtree('destination_directory')
  • shutil.rmtree():删除目录树,斩草除根!

    递归删除整个目录树,包括所有文件和子目录。

    import shutil
    import os
    
    # 创建一个目录树
    os.makedirs('my_directory/subdir')
    with open('my_directory/file1.txt', 'w') as f:
        f.write("File 1")
    with open('my_directory/subdir/file2.txt', 'w') as f:
        f.write("File 2")
    
    # 删除目录树
    shutil.rmtree('my_directory')
    print("目录树 'my_directory' 删除成功")
  • shutil.make_archive():压缩文件,打包带走!

    创建压缩文件,支持多种格式(zip, tar, gztar, bztar, xztar)。

    import shutil
    import os
    
    # 创建一个目录树
    os.makedirs('my_directory/subdir')
    with open('my_directory/file1.txt', 'w') as f:
        f.write("File 1")
    with open('my_directory/subdir/file2.txt', 'w') as f:
        f.write("File 2")
    
    # 压缩文件
    shutil.make_archive('my_archive', 'zip', 'my_directory')
    print("目录 'my_directory' 压缩为 'my_archive.zip' 成功")
    
    # 清理现场
    shutil.rmtree('my_directory')
    os.remove('my_archive.zip')
  • shutil.unpack_archive():解压缩文件,还原现场!

    解压缩文件。

    import shutil
    import os
    
    # 创建一个目录树
    os.makedirs('my_directory/subdir')
    with open('my_directory/file1.txt', 'w') as f:
        f.write("File 1")
    with open('my_directory/subdir/file2.txt', 'w') as f:
        f.write("File 2")
    
    # 压缩文件
    shutil.make_archive('my_archive', 'zip', 'my_directory')
    
    # 解压缩文件
    shutil.unpack_archive('my_archive.zip', 'extracted_directory')
    print("文件 'my_archive.zip' 解压缩到 'extracted_directory' 成功")
    
    # 清理现场
    shutil.rmtree('extracted_directory')
    os.remove('my_archive.zip')
    shutil.rmtree('my_directory')

4. 其他常用函数:

  • shutil.disk_usage():查看磁盘空间,心里有数!

    获取磁盘使用情况。

    import shutil
    
    total, used, free = shutil.disk_usage("/") #Linux
    #total, used, free = shutil.disk_usage("C:") #windows
    
    print(f"总空间: {total // (2**30)} GB")
    print(f"已用空间: {used // (2**30)} GB")
    print(f"可用空间: {free // (2**30)} GB")

总结:

ossysshutil 模块是Python与操作系统交互的三大利器。os 模块提供基本的操作系统功能,sys 模块提供对Python解释器的访问,shutil 模块提供高级的文件操作。掌握了这三个模块,你就可以编写出功能强大的Python脚本,自动化完成各种系统管理任务。

希望今天的分享对大家有所帮助!下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注