博客
关于我
Python3 shutil模块
阅读量:797 次
发布时间:2023-03-08

本文共 16434 字,大约阅读时间需要 54 分钟。

shutil 模块:Python 文件拷贝与管理

shutil 模块是 Python 标准库中用于文件操作的强大工具,提供了丰富的文件拷贝、目录管理和其他文件操作功能。以下是 shutil 模块的主要功能及其使用方法。


1. copyfileobj(fsrc, fdst, length=16*1024)

copyfileobj 用于将文件对象(如文件流)逐次拷贝到目标文件中。每次拷贝的默认大小为 16KB。

示例:

def copyfileobj(fsrc, fdst, length=16*1024):    """copy data from file-like object fsrc to file-like object fdst"""    while True:        buf = fsrc.read(length)        if not buf:            break        fdst.write(buf)

2. copyfile(src, dst, follow_symlinks=True)

copyfile 用于拷贝文件到目标路径。如果 follow_symlinks 未设置且源文件是符号链接,拷贝时会拷贝链接本身而非指向的文件。

参数:

  • follow_symlinks:控制是否跟随符号链接,默认为 True。

示例:

def copyfile(src, dst, *, follow_symlinks=True):    """Copy data from src to dst. If follow_symlinks is not set and src is a symbolic link, a new symlink will be created instead of copying the file it points to."""    if _samefile(src, dst):        raise SameFileError("{!r} and {!r} are the same file".format(src, dst))        for fn in [src, dst]:        try:            st = os.stat(fn)        except OSError:            pass        else:            if stat.S_ISFIFO(st.st_mode):                raise SpecialFileError("`%s` is a named pipe".format(fn))        if not follow_symlinks and os.path.islink(src):        os.symlink(os.readlink(src), dst)    else:        with open(src, 'rb') as fsrc:            with open(dst, 'wb') as fdst:                copyfileobj(fsrc, fdst)        return dst

3. copymode(src, dst, follow_symlinks=True)

copymode 用于拷贝文件的权限信息(如权限位、用户、组等)。如果 follow_symlinks 未设置且源和目标都是符号链接且系统支持 lchmod,则创建新的符号链接。

示例:

def copymode(src, dst, *, follow_symlinks=True):    """Copy mode bits from src to dst. If follow_symlinks is not set, symlinks aren't followed if and only if both `src` and `dst` are symlinks. If `lchmod` isn't available (e.g. Linux) this method does nothing."""    if not follow_symlinks and os.path.islink(src) and os.path.islink(dst):        if hasattr(os, 'lchmod'):            stat_func, chmod_func = os.lstat, os.lchmod        else:            return    elif hasattr(os, 'chmod'):        stat_func, chmod_func = os.stat, os.chmod    else:        return        st = stat_func(src)    chmod_func(dst, stat.S_IMODE(st.st_mode))

4. copystat(src, dst, follow_symlinks=True)

copystat 用于拷贝文件的状态信息(如权限位、访问时间、修改时间等)。如果 follow_symlinks 未设置且源和目标都是符号链接且系统支持 lchown,则创建新的符号链接。

示例:

def copystat(src, dst, *, follow_symlinks=True):    """Copy all stat info (mode bits, atime, mtime, flags) from src to dst. If the optional flag `follow_symlinks` is not set, symlinks aren't followed if and only if both `src` and `dst` are symlinks."""    def _nop(*args, ns=None, follow_symlinks=None):        pass        follow = follow_symlinks or not (os.path.islink(src) and os.path.islink(dst))        if follow:        def lookup(name):            return getattr(os, name, _nop)    else:        def lookup(name):            fn = getattr(os, name, _nop)            if fn in os.supports_follow_symlinks:                return fn            return _nop        st = lookup("stat")(src, follow_symlinks=follow)    mode = stat.S_IMODE(st.st_mode)    lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns), follow_symlinks=follow)        try:        lookup("chmod")(dst, mode, follow_symlinks=follow)    except NotImplementedError:        pass        if hasattr(st, 'st_flags'):        try:            lookup("chflags")(dst, st.st_flags, follow_symlinks=follow)        except OSError as why:            for err in 'EOPNOTSUPP', 'ENOTSUP':                if hasattr(errno, err) and why.errno == getattr(errno, err):                    break            else:                raise    _copyxattr(src, dst, follow_symlinks=follow)

5. copy(src, dst, follow_symlinks=True)

copy 用于完整拷贝文件和状态信息,默认使用 copy2 作为拷贝函数。

示例:

def copy(src, dst, *, follow_symlinks=True):    """Copy data and mode bits ("cp src dst"). Return the file's destination. The destination may be a directory."""    if os.path.isdir(dst):        dst = os.path.join(dst, os.path.basename(src))    copyfile(src, dst, follow_symlinks=follow_symlinks)    copymode(src, dst, follow_symlinks=follow_symlinks)    return dst

6. copy2(src, dst, follow_symlinks=True)

copy2 用于完整拷贝文件和状态信息,类似于 cp -p 的行为。

示例:

def copy2(src, dst, *, follow_symlinks=True):    """Copy data and all stat info ("cp -p src dst"). Return the file's destination."""    if os.path.isdir(dst):        dst = os.path.join(dst, os.path.basename(src))    copyfile(src, dst, follow_symlinks=follow_symlinks)    copystat(src, dst, follow_symlinks=follow_symlinks)    return dst

7. *ignore_patterns(patterns)

ignore_patterns 用于忽略特定文件或目录,可用于递归拷贝时排除不需要处理的文件。

示例:

def ignore_patterns(*patterns):    """Function that can be used as copytree() ignore parameter. Patterns is a sequence of glob-style patterns that are used to exclude files."""    def _ignore_patterns(path, names):        ignored_names = []        for pattern in patterns:            ignored_names.extend(fnmatch.filter(names, pattern))        return set(ignored_names)    return _ignore_patterns

8. copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False)

copytree 是递归拷贝目录树的核心函数,支持符号链接和忽略特定文件。

示例:

def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False):    """Recursively copy a directory tree. The destination directory must not already exist."""    names = os.listdir(src)    if ignore is not None:        ignored_names = ignore(src, names)    else:        ignored_names = set()        os.makedirs(dst)    errors = []        for name in names:        if name in ignored_names:            continue        srcname = os.path.join(src, name)        dstname = os.path.join(dst, name)                try:            if os.path.islink(srcname):                linkto = os.readlink(srcname)                if symlinks:                    os.symlink(linkto, dstname)                    copystat(srcname, dstname, follow_symlinks=not symlinks)                else:                    if not os.path.exists(linkto) and ignore_dangling_symlinks:                        continue                    if os.path.isdir(srcname):                        copytree(srcname, dstname, symlinks, ignore, copy_function)                    else:                        copy_function(srcname, dstname)            elif os.path.isdir(srcname):                copytree(srcname, dstname, symlinks, ignore, copy_function)            else:                copy_function(srcname, dstname)        except Error as err:            errors.extend(err.args[0])        except OSError as why:            errors.append((srcname, dstname, str(why)))        try:        copystat(src, dst)    except OSError as why:        if getattr(why, 'winerror', None) is None:            errors.append((src, dst, str(why)))        if errors:        raise Error(errors)    return dst

9. rmtree(path, ignore_errors=False, onerror=None)

rmtree 递归删除目录树,支持忽略错误和自定义错误处理函数。

示例:

def rmtree(path, ignore_errors=False, onerror=None):    """Recursively delete a directory tree. If ignore_errors is set, errors are ignored; otherwise, if onerror is set, it is called to handle the error."""    if ignore_errors:        def onerror(*args):            pass    elif onerror is None:        def onerror(*args):            raise        try:        orig_st = os.lstat(path)    except Exception:        onerror(os.lstat, path, sys.exc_info())        return        try:        fd = os.open(path, os.O_RDONLY)    except Exception:        onerror(os.lstat, path, sys.exc_info())        return        try:        if os.path.samestat(orig_st, os.fstat(fd)):            _rmtree_safe_fd(fd, path, onerror)            try:                os.rmdir(path)            except OSError:                onerror(os.rmdir, path, sys.exc_info())    except OSError:        if os.path.islink(path):            raise OSError("Cannot call rmtree on a symbolic link")        onerror(os.path.islink, path, sys.exc_info())        finally:        os.close(fd)

10. move(src, dst, copy_function=copy2)

move 递归移动文件或目录,类似于 mv 命令。

示例:

def move(src, dst, copy_function=copy2):    """Recursively move a file or directory to another location. This is similar to the Unix "mv" command."""    real_dst = dst    if os.path.isdir(dst):        real_dst = os.path.join(dst, _basename(src))        if os.path.exists(real_dst):            raise Error("Destination path '%s' already exists" % real_dst)        try:        os.rename(src, real_dst)    except OSError:        if os.path.islink(src):            linkto = os.readlink(src)            os.symlink(linkto, real_dst)            os.unlink(src)        elif os.path.isdir(src):            if _destinsrc(src, dst):                raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst))            copytree(src, real_dst, copy_function=copy_function, symlinks=True)            rmtree(src)        else:            copy_function(src, real_dst)            os.unlink(src)        return real_dst

11. get_archive_formats()

get_archive_formats 返回支持存档的格式列表。

示例:

def get_archive_formats():    """Returns a list of supported formats for archiving and unarchiving. Each element of the returned sequence is a tuple (name, description)."""    formats = [(name, registry[2]) for name, registry in _ARCHIVE_FORMATS.items()]    formats.sort()    return formats

12. register_archive_format(name, function, extra_args=None, description='')

注册自定义存档格式。

示例:

def register_archive_format(name, function, extra_args=None, description=''):    """Registers an archive format. name is the name of the format. function is the callable that will be used to create archives. If provided, extra_args is a sequence of (name, value) tuples that will be passed as arguments to the callable. description can be provided to describe the format, and will be returned by the get_archive_formats() function."""    if extra_args is None:        extra_args = []    if not callable(function):        raise TypeError('The %s object is not callable' % function)    if not isinstance(extra_args, (tuple, list)):        raise TypeError('extra_args needs to be a sequence')    for element in extra_args:        if not isinstance(element, (tuple, list)) or len(element) != 2:            raise TypeError('extra_args elements are : (arg_name, value)')        _ARCHIVE_FORMATS[name] = (function, extra_args, description)

13. unregister_archive_format(name)

取消注册的存档格式。

示例:

def unregister_archive_format(name):    """Delete the archive format registration for the specified name."""    if name in _ARCHIVE_FORMATS:        del _ARCHIVE_FORMATS[name]

14. make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, dry_run=0, owner=None, group=None, logger=None)

创建压缩包。

示例:

def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, dry_run=0, owner=None, group=None, logger=None):    """Create an archive file (eg. zip or tar). 'base_name' is the name of the file to create, minus any format-specific extension; 'format' is the archive format: one of "zip", "tar", "bztar" or "gztar". Returns the name of the archive file."""    save_cwd = os.getcwd()    if root_dir is not None:        if logger is not None:            logger.debug("changing into '%s'", root_dir)        base_name = os.path.abspath(base_name)        if not dry_run:            os.chdir(root_dir)        if base_dir is None:        base_dir = os.curdir        kwargs = {}    if dry_run:        kwargs['dry_run'] = dry_run        kwargs['logger'] = logger    try:        format_info = _ARCHIVE_FORMATS[format]    except KeyError:        raise ValueError("unknown archive format '%s'" % format)        func = format_info[0]    for arg, val in format_info[1]:        kwargs[arg] = val        if format != 'zip':        kwargs['owner'] = owner        kwargs['group'] = group        try:        filename = func(base_name, base_dir, **kwargs)    finally:        if root_dir is not None:            if logger is not None:                logger.debug("changing back to '%s'", save_cwd)            os.chdir(save_cwd)        return filename

15. get_unpack_formats()

返回支持解压的格式列表。

示例:

def get_unpack_formats():    """Returns a list of supported formats for unarchiving."""    formats = [(name, registry[1]) for name, registry in _UNPACK_FORMATS.items()]    formats.sort()    return formats

16. register_unpack_format(name, extensions, function, extra_args=None, description='')

注册自定义解压格式。

示例:

def register_unpack_format(name, extensions, function, extra_args=None, description=''):    """Register an unpack format. name is the format name, extensions is a list of file extensions that identify this format, function is the unpack function, extra_args is a list of (name, value) tuples for the function's arguments, and description is the format description."""    if not isinstance(extensions, (list, tuple)):        raise TypeError('extensions must be a list or tuple')    if not callable(function):        raise TypeError('The %s object is not callable' % function)    _UNPACK_FORMATS[name] = (extensions, function, extra_args, description)

17. unregister_unpack_format(name)

取消注册的解压格式。

示例:

def unregister_unpack_format(name):    """Unregister the unpack format for the specified name."""    if name in _UNPACK_FORMATS:        del _UNPACK_FORMATS[name]

18. unpack_archive(filename, extract_dir=None, format=None)

解压指定的存档文件。

示例:

def unpack_archive(filename, extract_dir=None, format=None):    """Unpack an archive. `filename` is the name 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", or "gztar". Or any other registered format. If not provided, unpack_archive will use the filename extension and see if an unpacker was registered for that extension. If none is found, a ValueError is raised."""    if extract_dir is None:        extract_dir = os.getcwd()        if format is not None:        try:            format_info = _UNPACK_FORMATS[format]        except KeyError:            raise ValueError("Unknown unpack format '{0}'".format(format))                func = format_info[1]        func(filename, extract_dir, **dict(format_info[2]))    else:        format = _find_unpack_format(filename)        if format is None:            raise ReadError("Unknown archive format '{0}'".format(filename))                func = _UNPACK_FORMATS[format][1]        kwargs = dict(_UNPACK_FORMATS[format][2])        func(filename, extract_dir, **kwargs)

19. chown(path, user=None, group=None)

chown 用于改变文件或目录的所有者和所属组。

示例:

def chown(path, user=None, group=None):    """Change owner user and group of the given path. user and group can be the uid/gid or the user/group names, and in that case, they are converted to their respective uid/gid."""    if user is None and group is None:        raise ValueError("user and/or group must be set")        _user = user    _group = group        if user is None:        _user = -1    elif isinstance(user, str):        _user = _get_uid(user)        if _user is None:            raise LookupError("no such user: {!r}".format(user))        if group is None:        _group = -1    elif not isinstance(group, int):        _group = _get_gid(group)        if _group is None:            raise LookupError("no such group: {!r}".format(group))        os.chown(path, _user, _group)

20. get_terminal_size(fallback=(80, 24))

获取终端窗口大小。

示例:

def get_terminal_size(fallback=(80, 24)):    """Get the terminal size. If the terminal cannot be queried, use the fallback value."""    try:        import termios        import os        size = termios_terminal_size()        return (size.ws_colnum, size.ws_rows)    except ImportError:        return fallback

21. which(cmd, mode=os.F_OK | os.X_OK, path=None)

查找命令路径。

示例:

def which(cmd, mode=os.F_OK | os.X_OK, path=None):    """Return the path of the command. If path is None, use os.environ.get('PATH'). If no such command exists, return None."""    if path is None:        path = os.environ.get('PATH', '')        if not path:        return None        for p in os.pathsep.split(path):        cmd_path = os.path.join(p, cmd)        if not os.path.isabs(cmd_path):            cmd_path = os.path.abspath(cmd_path)        if os.path.isfile(cmd_path):            if (os.access(cmd_path, mode) if mode                 else os.path.exists(cmd_path)):                return cmd_path    return None

通过这些函数,开发者可以高效地处理文件和目录的拷贝、移动、解压、管理权限等操作,shutil 模块为 Python 生态系统提供了强大的文件操作工具。

转载地址:http://sulfk.baihongyu.com/

你可能感兴趣的文章
python各种库安装
查看>>
python可视化matplotlib_如何使用Python中最强大的可视化工具Matplotlib?
查看>>
python可维护性_使用这7大神器,让你的Python 代码更容易于维护
查看>>
Python只运行一次while循环
查看>>
python变量的详细教程_Python零基础入门教程之语法入门[变量](第二期)
查看>>
Python变量命名方法-ChatGPT4o作答
查看>>
Python变量与运算符
查看>>
Python变量/运算符/函数/模块/string
查看>>
python发送邮件的时候出现 error (535, b‘5.7.3 Authentication unsuccessful‘) 解决方法
查看>>
python系列【仅供参考】:python flask框架 debug功能
查看>>
python发送notes邮件_使用python在Lotus Notes中发送邮件
查看>>
Python双版本下创建一个Scrapy(西瓜皮)项目
查看>>
Python双版本下No module named 'requests'
查看>>
python及pycharm2018软件安装教程
查看>>
python去重txt文本_Python实现的txt文件去重功能示例
查看>>
python去掉列表的逗号,从Python列表项中删除标点符号
查看>>
Python卸载所有包
查看>>
python单线程下实现多个socket并发
查看>>
Python单元测试框架介绍(超详细~)
查看>>
Python单元测试框架
查看>>