目录和文件操作¶
shutil.copyfileobj(fsrc, fdst[, length])¶
将 类文件对象 fsrc 的内容复制到类文件对象 fdst。如果给定整数 length,则它是缓冲区大小。特别是,负数 length 值表示在不循环遍历源数据块的情况下复制数据;默认情况下,数据以块的形式读取,以避免不受控制的内存消耗。请注意,如果 fsrc 对象的当前文件位置不是 0,则只会复制从当前文件位置到文件末尾的内容。
shutil.copyfile(src, dst, *, follow_symlinks=True)¶
将名为 src 的文件的内容(无元数据)复制到名为 dst 的文件,并以尽可能高效的方式返回 dst。src 和 dst 是路径类对象或以字符串形式给出的路径名。
dst 必须是完整的目标文件名;请查看 copy(),它接受目标目录路径进行复制。如果 src 和 dst 指定相同的文件,则会引发 SameFileError。
目标位置必须可写;否则,将引发 OSError 异常。如果 dst 已经存在,它将被替换。不能使用此函数复制字符或块设备和管道等特殊文件。
如果 follow_symlinks 为 false 且 src 是符号链接,则将创建一个新的符号链接,而不是复制 src 指向的文件。
引发带有参数 src、dst 的 审计事件 shutil.copyfile。
在 3.3 版本中更改: 以前引发 IOError 而不是 OSError。添加了 follow_symlinks 参数。现在返回 dst。
在 3.4 版本中更改: 引发 SameFileError 而不是 Error。由于前者是后者的子类,因此此更改向后兼容。
在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。
exception shutil.SameFileError¶
如果 copyfile() 中的源和目标是同一文件,则会引发此异常。
在 3.4 版本中添加。
shutil.copymode(src, dst, *, follow_symlinks=True)¶
将权限位从 src 复制到 dst。文件内容、所有者和组不受影响。src 和 dst 是路径类对象或以字符串形式给出的路径名。如果 follow_symlinks 为 false,并且 src 和 dst 都是符号链接,则 copymode() 将尝试修改 dst 本身的模式(而不是它指向的文件)。并非每个平台都提供此功能;有关详细信息,请参阅 copystat()。如果 copymode() 无法在本地平台上修改符号链接,并且要求这样做,它将不执行任何操作并返回。
引发带有参数 src、dst 的 审计事件 shutil.copymode。
在 3.3 版本中更改: 添加了 follow_symlinks 参数。
shutil.copystat(src, dst, *, follow_symlinks=True)¶
将权限位、上次访问时间、上次修改时间和标志从 src 复制到 dst。在 Linux 上,如果可能,copystat() 还会复制“扩展属性”。文件内容、所有者和组不受影响。src 和 dst 是路径类对象或以字符串形式给出的路径名。
如果 follow_symlinks 为 false,并且 src 和 dst 都指向符号链接,则 copystat() 将对符号链接本身进行操作,而不是符号链接引用的文件,从 src 符号链接读取信息,并将信息写入 dst 符号链接。
注意
并非所有平台都提供检查和修改符号链接的功能。Python 本身可以告诉您本地有哪些功能可用。
如果 os.chmod in os.supports_follow_symlinks 为 True,则 copystat() 可以修改符号链接的权限位。
如果 os.utime in os.supports_follow_symlinks 为 True,则 copystat() 可以修改符号链接的上次访问时间和修改时间。
如果 os.chflags in os.supports_follow_symlinks 为 True,copystat() 可以修改符号链接的标志。(os.chflags 并非在所有平台上都可用。)
在部分或全部功能不可用的平台上,当要求修改符号链接时,copystat() 将会复制它可以复制的所有内容。copystat() 永远不会返回失败。
请参阅 os.supports_follow_symlinks 获取更多信息。
引发一个 审计事件 shutil.copystat,参数为 src, dst。
3.3 版本更改: 添加了 follow_symlinks 参数,并支持 Linux 扩展属性。
shutil.copy(src, dst, *, follow_symlinks=True)¶
将文件 src 复制到文件或目录 dst。src 和 dst 应该是 路径类对象 或字符串。 如果 dst 指定一个目录,文件将会被复制到 dst 中,并使用 src 的基本文件名。 如果 dst 指定一个已经存在的文件,它将被替换。 返回新创建文件的路径。
如果 follow_symlinks 为 false,且 src 是一个符号链接,那么 dst 将被创建为一个符号链接。 如果 follow_symlinks 为 true 且 src 是一个符号链接,那么 dst 将会是 src 指向的文件的副本。
copy() 复制文件数据和文件的权限模式(请参阅 os.chmod())。其他元数据,如文件的创建和修改时间,不会被保留。要保留原始文件的所有元数据,请改用 copy2()。
引发带有参数 src、dst 的 审计事件 shutil.copyfile。
引发带有参数 src、dst 的 审计事件 shutil.copymode。
3.3 版本更改: 添加了 follow_symlinks 参数。现在返回新创建的文件的路径。
在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。
shutil.copy2(src, dst, *, follow_symlinks=True)¶
与 copy() 相同,除了 copy2() 还会尝试保留文件元数据。
当 follow_symlinks 为 false,且 src 是一个符号链接时,copy2() 会尝试将所有元数据从 src 符号链接复制到新创建的 dst 符号链接。 然而,此功能并非在所有平台上都可用。 在部分或全部功能不可用的平台上,copy2() 将会保留它可以保留的所有元数据; copy2() 永远不会因为无法保留文件元数据而引发异常。
copy2() 使用 copystat() 来复制文件元数据。 请参阅 copystat() 获取有关修改符号链接元数据的平台支持的更多信息。
引发带有参数 src、dst 的 审计事件 shutil.copyfile。
引发一个 审计事件 shutil.copystat,参数为 src, dst。
3.3 版本更改: 添加了 follow_symlinks 参数,尝试复制扩展文件系统属性(目前仅限 Linux)。现在返回新创建的文件的路径。
在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。
shutil.ignore_patterns(*patterns)¶
这个工厂函数创建一个函数,该函数可以用作 copytree() 的 ignore 参数的可调用对象,忽略与提供的 glob 风格 patterns 之一匹配的文件和目录。请参阅下面的示例。
shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False)¶
将根目录为 src 的整个目录树递归地复制到名为 dst 的目录,并返回目标目录。默认情况下,也将创建包含 dst 所需的所有中间目录。
目录的权限和时间使用 copystat() 复制,单个文件使用 copy2() 复制。
如果 symlinks 为 true,则源树中的符号链接在新树中表示为符号链接,并且原始链接的元数据将在平台允许的范围内进行复制;如果为 false 或省略,则将链接文件的内容和元数据复制到新树中。
当 symlinks 为 false 时,如果符号链接指向的文件不存在,则会在复制过程结束时在 Error 异常中引发的错误列表中添加一个异常。如果您想忽略此异常,可以将可选的 ignore_dangling_symlinks 标志设置为 true。请注意,此选项在不支持 os.symlink() 的平台上无效。
如果给定 ignore,则它必须是可调用对象,它将接收 copytree() 正在访问的目录及其内容的列表作为其参数,如 os.listdir() 返回的那样。由于 copytree() 是递归调用的,因此对于复制的每个目录,ignore 可调用对象将调用一次。该可调用对象必须返回相对于当前目录的目录和文件名序列(即其第二个参数中的项目子集);然后在复制过程中将忽略这些名称。ignore_patterns() 可用于创建基于 glob 风格模式忽略名称的此类可调用对象。
如果发生异常,则会引发一个 Error,其中包含一个原因列表。
如果给定 copy_function,则它必须是一个可调用对象,该对象将用于复制每个文件。它将使用源路径和目标路径作为参数调用。默认情况下,使用 copy2(),但可以使用任何支持相同签名的函数(如 copy())。
如果 dirs_exist_ok 为 false(默认值)并且 dst 已经存在,则会引发 FileExistsError。如果 dirs_exist_ok 为 true,则复制操作将在遇到现有目录时继续,并且 dst 树中的文件将被 src 树中的相应文件覆盖。
引发一个 审计事件 shutil.copytree,参数为 src,dst。
3.2 版本更改: 添加了 copy_function 参数,以便能够提供自定义的复制函数。添加了 ignore_dangling_symlinks 参数,以便在 symlinks 为 false 时忽略悬挂的符号链接错误。
3.3 版本更改: 当 symlinks 为 false 时,复制元数据。现在返回 dst。
在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。
3.8 版本更改: 添加了 dirs_exist_ok 参数。
shutil.rmtree(path, ignore_errors=False, onerror=None, *, onexc=None, dir_fd=None)¶
删除整个目录树;path 必须指向一个目录(但不能是指向目录的符号链接)。如果 ignore_errors 为 True,则会忽略因删除失败而产生的错误;如果为 False 或省略,则此类错误将通过调用由 onexc 或 onerror 指定的处理程序进行处理,或者如果两者都省略,则会将异常传播给调用方。
此函数可以支持相对于目录描述符的路径。
注意
在支持必要的文件描述符 (fd) 功能的平台上,默认使用 rmtree() 的防符号链接攻击版本。在其他平台上,rmtree() 的实现容易受到符号链接攻击:在适当的时机和情况下,攻击者可以操纵文件系统上的符号链接来删除他们原本无法访问的文件。应用程序可以使用 rmtree.avoids_symlink_attacks 函数属性来确定适用哪种情况。
如果提供了 onexc,它必须是一个可调用对象,接受三个参数:function、path 和 excinfo。
第一个参数 function 是引发异常的函数;它取决于平台和实现。第二个参数 path 将是传递给 function 的路径名称。第三个参数 excinfo 是引发的异常。由 onexc 引发的异常将不会被捕获。
已弃用的 onerror 类似于 onexc,不同之处在于它接收的第三个参数是从 sys.exc_info() 返回的元组。
引发一个带有参数 path、dir_fd 的审计事件 shutil.rmtree。
在 3.3 版本中更改: 添加了一个防符号链接攻击的版本,如果平台支持基于文件描述符的功能,则会自动使用。
在 3.8 版本中更改: 在 Windows 上,将不再删除目录连接的内容,然后再删除该连接。
在 3.11 版本中更改: 添加了 dir_fd 参数。
在 3.12 版本中更改: 添加了 onexc 参数,弃用了 onerror。
在 3.13 版本中更改: rmtree() 现在会忽略除了顶层路径之外的所有路径的 FileNotFoundError 异常。除了 OSError 和 OSError 子类的异常外,现在始终将其他异常传播给调用方。
rmtree.avoids_symlink_attacks¶
指示当前平台和实现是否提供了 rmtree() 的防符号链接攻击版本。目前,这仅适用于支持基于文件描述符的目录访问功能的平台。
3.3 版本中新增。
shutil.move(src, dst, copy_function=copy2)¶
递归地将文件或目录 (src) 移动到另一个位置并返回目标。
如果 dst 是一个现有目录或指向目录的符号链接,则 src 将被移动到该目录内部。该目录中的目标路径必须不存在。
如果 dst 已经存在但不是目录,则可能会根据 os.rename() 的语义覆盖它。
如果目标位于当前文件系统上,则使用 os.rename()。否则,使用 copy_function 将 src 复制到目标,然后删除 src。对于符号链接,将创建一个新的符号链接指向 src 的目标作为目标,并且将删除 src。
如果给定了 copy_function,它必须是一个可调用对象,接受两个参数,src 和目标,并且如果不能使用 os.rename(),则将使用它将 src 复制到目标。如果源是一个目录,则会调用 copytree(),并传递给它 copy_function。默认的 copy_function 是 copy2()。将 copy() 用作 copy_function 可以在无法复制元数据的情况下允许移动成功,但代价是不复制任何元数据。
引发一个带有参数 src、dst 的审计事件 shutil.move。
在 3.3 版本中更改: 为外部文件系统添加了显式的符号链接处理,从而使其适应 GNU 的 mv 的行为。现在返回 dst。
在 3.5 版本中更改: 添加了 copy_function 关键字参数。
在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。
在 3.9 版本中更改: 接受 src 和 dst 的 路径类对象。
shutil.disk_usage(path)¶
以具名元组的形式返回有关给定路径的磁盘使用情况统计信息,该具名元组具有属性 total、used 和 free,它们分别是总空间、已用空间和可用空间的大小(以字节为单位)。path 可以是文件或目录。
注意
在 Unix 文件系统上,path 必须指向 **已挂载** 文件系统分区中的路径。在这些平台上,CPython 不会尝试从非挂载的文件系统中检索磁盘使用信息。
3.3 版本中新增。
在 3.8 版本中更改: 在 Windows 上,path 现在可以是文件或目录。
可用性: Unix,Windows。
shutil.chown(path, user=None, group=None, *, dir_fd=None, follow_symlinks=True)¶
更改给定 path 的所有者 user 和/或 group。
user 可以是系统用户名或 uid;group 也是如此。至少需要一个参数。
另请参阅底层函数 os.chown()。
引发一个带有参数 path、user、group 的审计事件 shutil.chown。
可用性: Unix。
3.3 版本中新增。
3.13 版本更改: 添加了 dir_fd 和 follow_symlinks 参数。
shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None)¶
返回如果调用给定的 cmd 将要运行的可执行文件的路径。如果不会调用任何 cmd,则返回 None。
mode 是一个传递给 os.access() 的权限掩码,默认情况下确定文件是否存在以及是否可执行。
path 是一个 “PATH 字符串”,指定要查找的目录,以 os.pathsep 分隔。当没有指定 path 时,PATH 环境变量将从 os.environ 读取,如果未设置,则回退到 os.defpath。
在 Windows 上,如果 mode 不包括 os.X_OK,则当前目录会添加到 path 的前面。当 mode 包括 os.X_OK 时,将查询 Windows API NeedCurrentDirectoryForExePathW 以确定是否应将当前目录添加到 path 的前面。要避免为可执行文件查询当前工作目录:设置环境变量 NoDefaultCurrentDirectoryInExePath。
同样在 Windows 上,PATHEXT 环境变量用于解析可能尚未包含扩展名的命令。例如,如果您调用 shutil.which("python"),which() 将搜索 PATHEXT 以知道它应该在 path 目录中查找 python.exe。例如,在 Windows 上
>>> shutil.which("python")
'C:\\Python33\\python.EXE'
当 cmd 是包含目录组件的路径时,也会应用此规则。
>> shutil.which("C:\\Python33\\python")
'C:\\Python33\\python.EXE'
3.3 版本中新增。
3.8 版本更改: 现在接受 bytes 类型。如果 cmd 类型是 bytes,则结果类型也是 bytes。
3.12 版本更改: 在 Windows 上,如果 mode 包括 os.X_OK 并且 WinAPI NeedCurrentDirectoryForExePathW(cmd) 为 false,则不再将当前目录添加到搜索路径的前面,否则即使当前目录已在搜索路径中也会添加到前面;即使 cmd 包括目录组件或以 PATHEXT 中的扩展名结尾,现在也使用 PATHEXT;并且现在可以找到没有扩展名的文件名。
exception shutil.Error¶
此异常收集在多文件操作期间引发的异常。对于 copytree(),异常参数是 3 元组 (srcname, dstname, exception) 的列表。
平台相关的有效复制操作¶
从 Python 3.8 开始,所有涉及文件复制的函数(copyfile()、copy()、copy2()、copytree() 和 move())可能会使用平台特定的“快速复制”系统调用,以便更有效地复制文件(请参阅 bpo-33671)。“快速复制”意味着复制操作发生在内核中,避免像 “outfd.write(infd.read())” 那样在 Python 中使用用户空间缓冲区。
在 macOS 上,fcopyfile 用于复制文件内容(而不是元数据)。
在 Linux 上,使用 os.sendfile()。
在 Windows 上,shutil.copyfile() 使用更大的默认缓冲区大小(1 MiB 而不是 64 KiB)和基于 memoryview() 的 shutil.copyfileobj() 变体。
如果快速复制操作失败并且未在目标文件中写入任何数据,则 shutil 将在内部静默回退到使用效率较低的 copyfileobj() 函数。
3.8 版本更改。
copytree 示例¶
一个使用 ignore_patterns() 助手的示例
from shutil import copytree, ignore_patterns
copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
这将复制除 .pyc 文件和名称以 tmp 开头的文件或目录之外的所有内容。
另一个使用 ignore 参数添加日志调用的示例
from shutil import copytree
import logging
def _logpath(path, names):
logging.info('Working in %s', path)
return [] # nothing will be ignored
copytree(source, destination, ignore=_logpath)
rmtree 示例¶
此示例显示如何在 Windows 上删除目录树,其中某些文件设置了只读位。它使用 onexc 回调来清除只读位并重新尝试删除。任何后续失败都将传播。
import os, stat
import shutil
def remove_readonly(func, path, _):
"Clear the readonly bit and reattempt the removal"
os.chmod(path, stat.S_IWRITE)
func(path)
shutil.rmtree(directory, onexc=remove_readonly)