shutil
--- 高阶文件操作¶
源代码: Lib/shutil.py
shutil
模块提供了一系列对文件和文件集合的高阶操作。 特别是提供了一些支持文件拷贝和删除的函数。 对于单个文件的操作,请参阅 os
模块。
警告
即便是高阶文件拷贝函数 (shutil.copy()
, shutil.copy2()
) 也无法拷贝所有的文件元数据。
在 POSIX 平台上,这意味着将丢失文件所有者和组以及 ACL 数据。 在 Mac OS 上,资源钩子和其他元数据不被使用。 这意味着将丢失这些资源并且文件类型和创建者代码将不正确。 在 Windows 上,将不会拷贝文件所有者、ACL 和替代数据流。
目录和文件操作¶
-
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 为假值且 src 为符号链接,则将创建一个新的符号链接而不是拷贝 src 所指向的文件。
在 3.4 版更改: 引发
SameFileError
而不是Error
。 由于前者是后者的子类,此改变是向后兼容的。在 3.8 版更改: 可能会在内部使用平台专属的快速拷贝系统调用以更高效地拷贝文件。 参见 Platform-dependent efficient copy operations 一节。
-
exception
shutil.
SameFileError
¶ 此异常会在
copyfile()
中的源和目标为同一文件时被引发。3.4 新版功能.
-
shutil.
copymode
(src, dst, *, follow_symlinks=True)¶ Copy the permission bits from src to dst. The file contents, owner, and group are unaffected. src and dst are path-like objects or path names given as strings. If follow_symlinks is false, and both src and dst are symbolic links,
copymode()
will attempt to modify the mode of dst itself (rather than the file it points to). This functionality is not available on every platform; please seecopystat()
for more information. Ifcopymode()
cannot modify symbolic links on the local platform, and it is asked to do so, it will do nothing and return.在 3.3 版更改: 加入 follow_symlinks 参数。
-
shutil.
copystat
(src, dst, *, follow_symlinks=True)¶ Copy the permission bits, last access time, last modification time, and flags from src to dst. On Linux,
copystat()
also copies the "extended attributes" where possible. The file contents, owner, and group are unaffected. src and dst are path-like objects or path names given as strings.If follow_symlinks is false, and src and dst both refer to symbolic links,
copystat()
will operate on the symbolic links themselves rather than the files the symbolic links refer to—reading the information from the src symbolic link, and writing the information to the dst symbolic link.注解
Not all platforms provide the ability to examine and modify symbolic links. Python itself can tell you what functionality is locally available.
If
os.chmod in os.supports_follow_symlinks
isTrue
,copystat()
can modify the permission bits of a symbolic link.If
os.utime in os.supports_follow_symlinks
isTrue
,copystat()
can modify the last access and modification times of a symbolic link.If
os.chflags in os.supports_follow_symlinks
isTrue
,copystat()
can modify the flags of a symbolic link. (os.chflags
is not available on all platforms.)
On platforms where some or all of this functionality is unavailable, when asked to modify a symbolic link,
copystat()
will copy everything it can.copystat()
never returns failure.Please see
os.supports_follow_symlinks
for more information.在 3.3 版更改: Added follow_symlinks argument and support for Linux extended attributes.
-
shutil.
copy
(src, dst, *, follow_symlinks=True)¶ Copies the file src to the file or directory dst. src and dst should be strings. If dst specifies a directory, the file will be copied into dst using the base filename from src. Returns the path to the newly created file.
If follow_symlinks is false, and src is a symbolic link, dst will be created as a symbolic link. If follow_symlinks is true and src is a symbolic link, dst will be a copy of the file src refers to.
copy()
copies the file data and the file's permission mode (seeos.chmod()
). Other metadata, like the file's creation and modification times, is not preserved. To preserve all file metadata from the original, usecopy2()
instead.在 3.3 版更改: Added follow_symlinks argument. Now returns path to the newly created file.
在 3.8 版更改: 可能会在内部使用平台专属的快速拷贝系统调用以更高效地拷贝文件。 参见 Platform-dependent efficient copy operations 一节。
-
shutil.
copy2
(src, dst, *, follow_symlinks=True)¶ Identical to
copy()
except thatcopy2()
also attempts to preserve file metadata.When follow_symlinks is false, and src is a symbolic link,
copy2()
attempts to copy all metadata from the src symbolic link to the newly-created dst symbolic link. However, this functionality is not available on all platforms. On platforms where some or all of this functionality is unavailable,copy2()
will preserve all the metadata it can;copy2()
never raises an exception because it cannot preserve file metadata.copy2()
usescopystat()
to copy the file metadata. Please seecopystat()
for more information about platform support for modifying symbolic link metadata.在 3.3 版更改: Added follow_symlinks argument, try to copy extended file system attributes too (currently Linux only). Now returns path to the newly created file.
在 3.8 版更改: 可能会在内部使用平台专属的快速拷贝系统调用以更高效地拷贝文件。 参见 Platform-dependent efficient copy operations 一节。
-
shutil.
ignore_patterns
(*patterns)¶ This factory function creates a function that can be used as a callable for
copytree()
's ignore argument, ignoring files and directories that match one of the glob-style patterns provided. See the example below.
-
shutil.
copytree
(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False)¶ Recursively copy an entire directory tree rooted at src to a directory named dst and return the destination directory. dirs_exist_ok dictates whether to raise an exception in case dst or any missing parent directory already exists.
Permissions and times of directories are copied with
copystat()
, individual files are copied usingcopy2()
.If symlinks is true, symbolic links in the source tree are represented as symbolic links in the new tree and the metadata of the original links will be copied as far as the platform allows; if false or omitted, the contents and metadata of the linked files are copied to the new tree.
When symlinks is false, if the file pointed by the symlink doesn't exist, an exception will be added in the list of errors raised in an
Error
exception at the end of the copy process. You can set the optional ignore_dangling_symlinks flag to true if you want to silence this exception. Notice that this option has no effect on platforms that don't supportos.symlink()
.If ignore is given, it must be a callable that will receive as its arguments the directory being visited by
copytree()
, and a list of its contents, as returned byos.listdir()
. Sincecopytree()
is called recursively, the ignore callable will be called once for each directory that is copied. The callable must return a sequence of directory and file names relative to the current directory (i.e. a subset of the items in its second argument); these names will then be ignored in the copy process.ignore_patterns()
can be used to create such a callable that ignores names based on glob-style patterns.If exception(s) occur, an
Error
is raised with a list of reasons.If copy_function is given, it must be a callable that will be used to copy each file. It will be called with the source path and the destination path as arguments. By default,
copy2()
is used, but any function that supports the same signature (likecopy()
) can be used.Raises an auditing event
shutil.copytree
with argumentssrc
,dst
.在 3.3 版更改: Copy metadata when symlinks is false. Now returns dst.
在 3.2 版更改: Added the copy_function argument to be able to provide a custom copy function. Added the ignore_dangling_symlinks argument to silent dangling symlinks errors when symlinks is false.
在 3.8 版更改: 可能会在内部使用平台专属的快速拷贝系统调用以更高效地拷贝文件。 参见 Platform-dependent efficient copy operations 一节。
3.8 新版功能: The dirs_exist_ok parameter.
-
shutil.
rmtree
(path, ignore_errors=False, onerror=None)¶ Delete an entire directory tree; path must point to a directory (but not a symbolic link to a directory). If ignore_errors is true, errors resulting from failed removals will be ignored; if false or omitted, such errors are handled by calling a handler specified by onerror or, if that is omitted, they raise an exception.
注解
On platforms that support the necessary fd-based functions a symlink attack resistant version of
rmtree()
is used by default. On other platforms, thermtree()
implementation is susceptible to a symlink attack: given proper timing and circumstances, attackers can manipulate symlinks on the filesystem to delete files they wouldn't be able to access otherwise. Applications can use thermtree.avoids_symlink_attacks
function attribute to determine which case applies.If onerror is provided, it must be a callable that accepts three parameters: function, path, and excinfo.
The first parameter, function, is the function which raised the exception; it depends on the platform and implementation. The second parameter, path, will be the path name passed to function. The third parameter, excinfo, will be the exception information returned by
sys.exc_info()
. Exceptions raised by onerror will not be caught.Raises an auditing event
shutil.rmtree
with argumentpath
.在 3.3 版更改: Added a symlink attack resistant version that is used automatically if platform supports fd-based functions.
在 3.8 版更改: On Windows, will no longer delete the contents of a directory junction before removing the junction.
-
shutil.
move
(src, dst, copy_function=copy2)¶ Recursively move a file or directory (src) to another location (dst) and return the destination.
If the destination is an existing directory, then src is moved inside that directory. If the destination already exists but is not a directory, it may be overwritten depending on
os.rename()
semantics.If the destination is on the current filesystem, then
os.rename()
is used. Otherwise, src is copied to dst using copy_function and then removed. In case of symlinks, a new symlink pointing to the target of src will be created in or as dst and src will be removed.If copy_function is given, it must be a callable that takes two arguments src and dst, and will be used to copy src to dest if
os.rename()
cannot be used. If the source is a directory,copytree()
is called, passing it thecopy_function()
. The default copy_function iscopy2()
. Usingcopy()
as the copy_function allows the move to succeed when it is not possible to also copy the metadata, at the expense of not copying any of the metadata.在 3.3 版更改: Added explicit symlink handling for foreign filesystems, thus adapting it to the behavior of GNU's mv. Now returns dst.
在 3.5 版更改: Added the copy_function keyword argument.
在 3.8 版更改: 可能会在内部使用平台专属的快速拷贝系统调用以更高效地拷贝文件。 参见 Platform-dependent efficient copy operations 一节。
-
shutil.
disk_usage
(path)¶ Return disk usage statistics about the given path as a named tuple with the attributes total, used and free, which are the amount of total, used and free space, in bytes. path may be a file or a directory.
3.3 新版功能.
在 3.8 版更改: On Windows, path can now be a file or directory.
可用性: Unix, Windows。
-
shutil.
chown
(path, user=None, group=None)¶ Change owner user and/or group of the given path.
user can be a system user name or a uid; the same applies to group. At least one argument is required.
See also
os.chown()
, the underlying function.Availability: Unix.
3.3 新版功能.
-
shutil.
which
(cmd, mode=os.F_OK | os.X_OK, path=None)¶ Return the path to an executable which would be run if the given cmd was called. If no cmd would be called, return
None
.mode is a permission mask passed to
os.access()
, by default determining if the file exists and executable.When no path is specified, the results of
os.environ()
are used, returning either the "PATH" value or a fallback ofos.defpath
.On Windows, the current directory is always prepended to the path whether or not you use the default or provide your own, which is the behavior the command shell uses when finding executables. Additionally, when finding the cmd in the path, the
PATHEXT
environment variable is checked. For example, if you callshutil.which("python")
,which()
will searchPATHEXT
to know that it should look forpython.exe
within the path directories. For example, on Windows:>>> shutil.which("python") 'C:\\Python33\\python.EXE'
3.3 新版功能.
-
exception
shutil.
Error
¶ This exception collects exceptions that are raised during a multi-file operation. For
copytree()
, the exception argument is a list of 3-tuples (srcname, dstname, exception).
Platform-dependent efficient copy operations¶
Starting from Python 3.8 all functions involving a file copy (copyfile()
,
copy()
, copy2()
, copytree()
, and move()
) may use
platform-specific "fast-copy" syscalls in order to copy the file more
efficiently (see bpo-33671).
"fast-copy" means that the copying operation occurs within the kernel, avoiding
the use of userspace buffers in Python as in "outfd.write(infd.read())
".
On macOS fcopyfile is used to copy the file content (not metadata).
On Linux os.sendfile()
is used.
On Windows shutil.copyfile()
uses a bigger default buffer size (1 MiB
instead of 64 KiB) and a memoryview()
-based variant of
shutil.copyfileobj()
is used.
If the fast-copy operation fails and no data was written in the destination
file then shutil will silently fallback on using less efficient
copyfileobj()
function internally.
在 3.8 版更改.
copytree 示例¶
This example is the implementation of the copytree()
function, described
above, with the docstring omitted. It demonstrates many of the other functions
provided by this module.
def copytree(src, dst, symlinks=False):
names = os.listdir(src)
os.makedirs(dst)
errors = []
for name in names:
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks)
else:
copy2(srcname, dstname)
# XXX What about devices, sockets etc.?
except OSError as why:
errors.append((srcname, dstname, str(why)))
# catch the Error from the recursive copytree so that we can
# continue with other files
except Error as err:
errors.extend(err.args[0])
try:
copystat(src, dst)
except OSError as why:
# can't copy file access times on Windows
if why.winerror is None:
errors.extend((src, dst, str(why)))
if errors:
raise Error(errors)
Another example that uses the ignore_patterns()
helper:
from shutil import copytree, ignore_patterns
copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
This will copy everything except .pyc
files and files or directories whose
name starts with tmp
.
Another example that uses the ignore argument to add a logging call:
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 示例¶
This example shows how to remove a directory tree on Windows where some of the files have their read-only bit set. It uses the onerror callback to clear the readonly bit and reattempt the remove. Any subsequent failure will propagate.
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, onerror=remove_readonly)
归档操作¶
3.2 新版功能.
在 3.5 版更改: Added support for the xztar format.
High-level utilities to create and read compressed and archived files are also
provided. They rely on the zipfile
and tarfile
modules.
-
shutil.
make_archive
(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])¶ Create an archive file (such as zip or tar) and return its name.
base_name is the name of the file to create, including the path, minus any format-specific extension. format is the archive format: one of "zip" (if the
zlib
module is available), "tar", "gztar" (if thezlib
module is available), "bztar" (if thebz2
module is available), or "xztar" (if thelzma
module is available).root_dir is a directory that will be the root directory of the archive; for example, we typically chdir into root_dir before creating the archive.
base_dir is the directory where we start archiving from; i.e. base_dir will be the common prefix of all files and directories in the archive.
root_dir and base_dir both default to the current directory.
If dry_run is true, no archive is created, but the operations that would be executed are logged to logger.
owner and group are used when creating a tar archive. By default, uses the current owner and group.
logger must be an object compatible with PEP 282, usually an instance of
logging.Logger
.The verbose argument is unused and deprecated.
Raises an auditing event
shutil.make_archive
with argumentsbase_name
,format
,root_dir
,base_dir
.在 3.8 版更改: The modern pax (POSIX.1-2001) format is now used instead of the legacy GNU format for archives created with
format="tar"
.
-
shutil.
get_archive_formats
()¶ Return a list of supported formats for archiving. Each element of the returned sequence is a tuple
(name, description)
.By default
shutil
provides these formats:zip: ZIP file (if the
zlib
module is available).tar: Uncompressed tar file. Uses POSIX.1-2001 pax format for new archives.
gztar: gzip'ed tar-file (if the
zlib
module is available).bztar: bzip2'ed tar-file (if the
bz2
module is available).xztar: xz'ed tar-file (if the
lzma
module is available).
You can register new formats or provide your own archiver for any existing formats, by using
register_archive_format()
.
-
shutil.
register_archive_format
(name, function[, extra_args[, description]])¶ Register an archiver for the format name.
function is the callable that will be used to unpack archives. The callable will receive the base_name of the file to create, followed by the base_dir (which defaults to
os.curdir
) to start archiving from. Further arguments are passed as keyword arguments: owner, group, dry_run and logger (as passed inmake_archive()
).If given, extra_args is a sequence of
(name, value)
pairs that will be used as extra keywords arguments when the archiver callable is used.description is used by
get_archive_formats()
which returns the list of archivers. Defaults to an empty string.
-
shutil.
unregister_archive_format
(name)¶ Remove the archive format name from the list of supported formats.
-
shutil.
unpack_archive
(filename[, extract_dir[, format]])¶ Unpack an archive. filename is the full path of the archive.
extract_dir is the name of the target directory where the archive is unpacked. If not provided, the current working directory is used.
format is the archive format: one of "zip", "tar", "gztar", "bztar", or "xztar". Or any other format registered with
register_unpack_format()
. If not provided,unpack_archive()
will use the archive file name extension and see if an unpacker was registered for that extension. In case none is found, aValueError
is raised.在 3.7 版更改: Accepts a path-like object for filename and extract_dir.
-
shutil.
register_unpack_format
(name, extensions, function[, extra_args[, description]])¶ Registers an unpack format. name is the name of the format and extensions is a list of extensions corresponding to the format, like
.zip
for Zip files.function is the callable that will be used to unpack archives. The callable will receive the path of the archive, followed by the directory the archive must be extracted to.
When provided, extra_args is a sequence of
(name, value)
tuples that will be passed as keywords arguments to the callable.description can be provided to describe the format, and will be returned by the
get_unpack_formats()
function.
-
shutil.
unregister_unpack_format
(name)¶ Unregister an unpack format. name is the name of the format.
-
shutil.
get_unpack_formats
()¶ Return a list of all registered formats for unpacking. Each element of the returned sequence is a tuple
(name, extensions, description)
.By default
shutil
provides these formats:zip: ZIP file (unpacking compressed files works only if the corresponding module is available).
tar: uncompressed tar file.
gztar: gzip'ed tar-file (if the
zlib
module is available).bztar: bzip2'ed tar-file (if the
bz2
module is available).xztar: xz'ed tar-file (if the
lzma
module is available).
You can register new formats or provide your own unpacker for any existing formats, by using
register_unpack_format()
.
Archiving example¶
In this example, we create a gzip'ed tar-file archive containing all files
found in the .ssh
directory of the user:
>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))
>>> make_archive(archive_name, 'gztar', root_dir)
'/Users/tarek/myarchive.tar.gz'
The resulting archive contains:
$ tar -tzvf /Users/tarek/myarchive.tar.gz
drwx------ tarek/staff 0 2010-02-01 16:23:40 ./
-rw-r--r-- tarek/staff 609 2008-06-09 13:26:54 ./authorized_keys
-rwxr-xr-x tarek/staff 65 2008-06-09 13:26:54 ./config
-rwx------ tarek/staff 668 2008-06-09 13:26:54 ./id_dsa
-rwxr-xr-x tarek/staff 609 2008-06-09 13:26:54 ./id_dsa.pub
-rw------- tarek/staff 1675 2008-06-09 13:26:54 ./id_rsa
-rw-r--r-- tarek/staff 397 2008-06-09 13:26:54 ./id_rsa.pub
-rw-r--r-- tarek/staff 37192 2010-02-06 18:23:10 ./known_hosts
Querying the size of the output terminal¶
-
shutil.
get_terminal_size
(fallback=(columns, lines))¶ Get the size of the terminal window.
For each of the two dimensions, the environment variable,
COLUMNS
andLINES
respectively, is checked. If the variable is defined and the value is a positive integer, it is used.When
COLUMNS
orLINES
is not defined, which is the common case, the terminal connected tosys.__stdout__
is queried by invokingos.get_terminal_size()
.If the terminal size cannot be successfully queried, either because the system doesn't support querying, or because we are not connected to a terminal, the value given in
fallback
parameter is used.fallback
defaults to(80, 24)
which is the default size used by many terminal emulators.The value returned is a named tuple of type
os.terminal_size
.See also: The Single UNIX Specification, Version 2, Other Environment Variables.
3.3 新版功能.