ZetCode

Python os.rename 函数

上次修改时间:2025 年 4 月 11 日

这份全面指南探讨了 Python 的 os.rename 函数,该函数用于重命名文件和目录。我们将介绍基本用法、错误处理、跨平台注意事项和实际示例。

基本定义

os.rename 函数更改文件或目录的名称。它接受两个参数:src(源路径)和 dst(目标路径)。

在 Unix 系统上,这等效于 rename 系统调用。在 Windows 上,它使用 MoveFileEx。如果操作失败,该函数会引发 OSError。

基本文件重命名

os.rename 的最简单用法是更改同一目录中文件的名称。此示例演示了重命名单个文件。

basic_rename.py
import os

# Original and new file names
src = "old_name.txt"
dst = "new_name.txt"

# Create the original file
with open(src, "w") as f:
    f.write("Sample content")

# Rename the file
try:
    os.rename(src, dst)
    print(f"Renamed {src} to {dst}")
except OSError as e:
    print(f"Error renaming file: {e}")

# Verify the rename
if os.path.exists(dst):
    print("Rename successful")
else:
    print("Rename failed")

此示例创建一个文件,重命名它,并验证操作。try-except 块处理重命名操作期间的潜在错误。

请注意,如果 dst 已经存在,则行为取决于操作系统。在 Unix 上,它将覆盖;在 Windows 上,它将引发错误。

在目录之间移动文件

当路径包含不同的目录组件时,os.rename 还可以移动目录之间的文件。此示例显示目录移动。

move_between_dirs.py
import os

# Create directories and file
os.makedirs("source_dir", exist_ok=True)
os.makedirs("target_dir", exist_ok=True)
src = os.path.join("source_dir", "file.txt")

with open(src, "w") as f:
    f.write("Moving this file")

# Move file to target directory
dst = os.path.join("target_dir", "file.txt")

try:
    os.rename(src, dst)
    print(f"Moved {src} to {dst}")
except OSError as e:
    print(f"Error moving file: {e}")

# Clean up
if os.path.exists(dst):
    os.remove(dst)
os.rmdir("source_dir")
os.rmdir("target_dir")

这会创建源目录和目标目录,在它们之间移动文件,然后清理。os.path.join 确保跨平台的正确路径构造。

如果目录已存在,exist_ok 参数可防止出错。始终使用 os.path.join 进行跨平台路径操作。

重命名目录

os.rename 的工作方式与文件一样适用于目录。此示例演示了重命名整个目录及其内容。

rename_directory.py
import os

# Create directory with content
os.makedirs("old_dir", exist_ok=True)
with open(os.path.join("old_dir", "test.txt"), "w") as f:
    f.write("Directory rename test")

# Rename the directory
try:
    os.rename("old_dir", "new_dir")
    print("Directory renamed successfully")
    
    # Verify contents moved
    if os.path.exists(os.path.join("new_dir", "test.txt")):
        print("Contents preserved in new directory")
except OSError as e:
    print(f"Error renaming directory: {e}")

# Clean up
if os.path.exists("new_dir"):
    os.remove(os.path.join("new_dir", "test.txt"))
    os.rmdir("new_dir")

这会创建一个包含文件的目录,重命名该目录,并验证内容是否已保留。目录重命名遵循与文件相同的规则。

在 Unix 系统上,目录必须为空或位于同一文件系统上。Windows 对打开的文件和权限有不同的限制。

错误处理

正确的错误处理对于可靠的文件操作至关重要。此示例显示了常见的错误场景以及如何处理它们。

error_handling.py
import os
import errno

def safe_rename(src, dst):
    try:
        os.rename(src, dst)
        return True
    except OSError as e:
        if e.errno == errno.ENOENT:
            print(f"Source file {src} does not exist")
        elif e.errno == errno.EACCES:
            print(f"Permission denied for {src} or {dst}")
        elif e.errno == errno.EEXIST:
            print(f"Destination {dst} already exists")
        else:
            print(f"Error renaming {src} to {dst}: {e}")
        return False

# Test cases
safe_rename("nonexistent.txt", "new.txt")  # ENOENT
safe_rename("/root/file.txt", "new.txt")   # EACCES (Unix)
safe_rename("file1.txt", "file2.txt")      # EEXIST (Windows)
safe_rename("valid.txt", "renamed.txt")    # Success case

这演示了处理各种错误情况:缺少源文件、权限问题和现有目标文件。errno 模块提供标准错误代码。

Windows 和 Unix 可能会为类似的情况返回不同的错误代码。始终在目标平台上测试错误处理。

跨平台注意事项

文件重命名行为因操作系统而异。此示例突出显示了关键差异并提供了跨平台解决方案。

cross_platform.py
import os
import platform
import shutil

def cross_rename(src, dst):
    try:
        os.rename(src, dst)
    except OSError:
        # Fallback for Windows when dst exists
        if platform.system() == "Windows":
            try:
                os.replace(src, dst)
            except OSError as e:
                print(f"Windows-specific error: {e}")
        # Fallback for cross-device moves on Unix
        elif errno.EXDEV:
            shutil.move(src, dst)
        else:
            raise

# Usage example
cross_rename("source.txt", "destination.txt")

这显示了处理平台特定的行为:Windows 默认不允许覆盖,而 Unix 不能跨文件系统重命名。

该解决方案在 Windows 上使用 os.replace,在 Unix 上使用 shutil.move 进行跨设备移动。重命名文件时,请始终考虑目标平台。

原子重命名操作

文件重命名通常是原子操作,使其对于确保数据一致性非常有用。此示例演示了原子文件替换。

atomic_rename.py
import os
import tempfile

def atomic_write(filename, data):
    # Write to temporary file
    temp = tempfile.NamedTemporaryFile(delete=False, dir=os.path.dirname(filename))
    try:
        with temp:
            temp.write(data.encode())
        
        # Atomic rename
        os.replace(temp.name, filename)
    except Exception:
        os.unlink(temp.name)
        raise

# Usage
atomic_write("important.dat", "Critical data")

这会创建一个临时文件,将数据写入其中,然后原子地替换目标文件。这确保目标文件是完整的或未更改的。

原子操作对于数据完整性至关重要。在 Unix 上,os.rename 是原子的;在 Windows 上,使用 os.replace 实现类似的行为。

批量重命名文件

os.rename 可以与其他函数结合使用以进行批量处理。此示例使用模式重命名多个文件。

batch_rename.py
import os
import re

def batch_rename(directory, pattern, replacement):
    for filename in os.listdir(directory):
        if re.match(pattern, filename):
            new_name = re.sub(pattern, replacement, filename)
            src = os.path.join(directory, filename)
            dst = os.path.join(directory, new_name)
            try:
                os.rename(src, dst)
                print(f"Renamed {filename} to {new_name}")
            except OSError as e:
                print(f"Error renaming {filename}: {e}")

# Usage: prefix all .txt files with "backup_"
batch_rename(".", r"^(.*\.txt)$", r"backup_\1")

此函数重命名目录中所有与正则表达式匹配的文件。该示例将 "backup_" 前缀添加到所有 .txt 文件。

在批量操作之前,始终在样本数据上测试模式匹配。考虑用于生产代码的试运行模式。

安全注意事项

最佳实践

资料来源

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有 Python 教程