shutil模块

-- --High-level file operations  高级的文件操作模块。

  os模块提供了对目录或者文件的新建/删除/查看文件属性,还提供了对文件以及目录的路径操作。比如说:绝对路径,父目录……  但是,os文件的操作还应该包含移动 复制  打包 压缩 解压等操作,这些os模块都没有提供。

  而本章所讲的shutil则就是对os中文件操作的补充。--移动 复制  打包 压缩 解压,

shutil功能:

1  shutil.copyfileobj(fsrc, fdst[, length=16*1024])    #copy文件内容到另一个文件,可以copy指定大小的内容

#先来看看其源代码。
def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
while 1:
buf = fsrc.read(length)
if not buf:
break
fdst.write(buf) #注意! 在其中fsrc,fdst都是文件对象,都需要打开后才能进行复制操作
import shutil
f1=open('name','r')
f2=open('name_copy','w+')
shutil.copyfileobj(f1,f2,length=16*1024)

2  shutil.copyfile(src,dst)   #copy文件内容,是不是感觉上面的文件复制很麻烦?还需要自己手动用open函数打开文件,在这里就不需要了,事实上,copyfile调用了copyfileobj

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:
# File most likely does not exist
pass
else:
# XXX What about other special files? (sockets, devices...)
if stat.S_ISFIFO(st.st_mode):
raise SpecialFileError("`%s` is a named pipe" % 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 查看源代码

查看源码

shutil.copyfile('name','name_copy_2')
#一句就可以实现复制文件内容

实例

3  shutil.copymode(src,dst)   #仅copy权限,不更改文件内容,组和用户。

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)) 查看源代码

查看源码

#先看两个文件的权限
[root@slyoyo python_test]# ls -l
total 4
-rw-r--r--. 1 root root 79 May 14 05:17 test1
-rwxr-xr-x. 1 root root 0 May 14 19:10 test2 #运行命令
>>> import shutil
>>> shutil.copymode('test1','test2') #查看结果
[root@slyoyo python_test]# ls -l
total 4
-rw-r--r--. 1 root root 79 May 14 05:17 test1
-rw-r--r--. 1 root root 0 May 14 19:10 test2 #当我们将目标文件换为一个不存在的文件时报错
>>> shutil.copymode('test1','test3')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/python/lib/python3.4/shutil.py", line 132, in copymode
chmod_func(dst, stat.S_IMODE(st.st_mode))
FileNotFoundError: [Errno 2] No such file or directory: 'test233'

实例

4  shutil.copystat(src,dst)    #复制所有的状态信息,包括权限,组,用户,时间等

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 symlinks (aka don't not follow symlinks)
follow = follow_symlinks or not (os.path.islink(src) and os.path.islink(dst))
if follow:
# use the real function if it exists
def lookup(name):
return getattr(os, name, _nop)
else:
# use the real function only if it exists
# *and* it supports follow_symlinks
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:
# if we got a NotImplementedError, it's because
# * follow_symlinks=False,
# * lchown() is unavailable, and
# * either
# * fchownat() is unavailable or
# * fchownat() doesn't implement AT_SYMLINK_NOFOLLOW.
# (it returned ENOSUP.)
# therefore we're out of options--we simply cannot chown the
# symlink. give up, suppress the error.
# (which is what shutil always did in this circumstance.)
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  shutil.copy(src,dst)   #复制文件的内容以及权限,先copyfile后copymode

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 follow_symlinks is false, symlinks won't be followed. This
resembles GNU's "cp -P src dst". If source and destination are the same file, a SameFileError will be
raised. """
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  shutil.copy2(src,dst)    #复制文件的内容以及文件的所有状态信息。先copyfile后copystat

def copy2(src, dst, *, follow_symlinks=True):
"""Copy data and all stat info ("cp -p src dst"). Return the file's
destination." The destination may be a directory. If follow_symlinks is false, symlinks won't be followed. This
resembles GNU's "cp -P src dst". """
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  shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,ignore_dangling_symlinks=False)   #递归的复制文件内容及状态信息

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.
If exception(s) occur, an Error is raised with a list of reasons. If the optional symlinks flag is true, symbolic links in the
source tree result in symbolic links in the destination tree; if
it is false, the contents of the files pointed to by symbolic
links are copied. 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 has no effect on
platforms that don't support os.symlink. The optional ignore argument is a callable. If given, it
is called with the `src` parameter, which is the directory
being visited by copytree(), and `names` which is the list of
`src` contents, as returned by os.listdir(): callable(src, names) -> ignored_names Since copytree() is called recursively, the callable will be
called once for each directory that is copied. It returns a
list of names relative to the `src` directory that should
not be copied. The optional copy_function argument is 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 (like copy()) can be used. """
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:
# We can't just leave it to `copy_function` because legacy
# code with a custom `copy_function` may rely on copytree
# doing the right thing.
os.symlink(linkto, dstname)
copystat(srcname, dstname, follow_symlinks=not symlinks)
else:
# ignore dangling symlink if the flag is on
if not os.path.exists(linkto) and ignore_dangling_symlinks:
continue
# otherwise let the copy occurs. copy2 will raise an error
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:
# Will raise a SpecialFileError for unsupported file types
copy_function(srcname, dstname)
# catch the Error from the recursive copytree so that we can
# continue with other files
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:
# Copying file access times may fail on Windows
if getattr(why, 'winerror', None) is None:
errors.append((src, dst, str(why)))
if errors:
raise Error(errors)
return dst # version vulnerable to race conditions

查看源代码

[root@slyoyo python_test]# tree copytree_test/
copytree_test/
└── test
├── test1
├── test2
└── hahaha [root@slyoyo test]# ls -l
total 0
-rw-r--r--. 1 python python 0 May 14 19:36 hahaha
-rw-r--r--. 1 python python 0 May 14 19:36 test1
-rw-r--r--. 1 root root 0 May 14 19:36 test2 >>> shutil.copytree('copytree_test','copytree_copy')
'copytree_copy' [root@slyoyo python_test]# ls -l
total 12
drwxr-xr-x. 3 root root 4096 May 14 19:36 copytree_copy
drwxr-xr-x. 3 root root 4096 May 14 19:36 copytree_test
-rw-r--r--. 1 python python 79 May 14 05:17 test1
-rw-r--r--. 1 root root 0 May 14 19:10 test2
[root@slyoyo python_test]# tree copytree_copy/
copytree_copy/
└── test
├── hahaha
├── test1
└── test2

实例

8  shutil.rmtree(path, ignore_errors=False, onerror=None)   #递归地删除文件

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 with arguments (func,
path, exc_info) where func is platform and implementation dependent;
path is the argument to that function that caused it to fail; and
exc_info is a tuple returned by sys.exc_info(). If ignore_errors
is false and onerror is None, an exception is raised. """
if ignore_errors:
def onerror(*args):
pass
elif onerror is None:
def onerror(*args):
raise
if _use_fd_functions:
# While the unsafe rmtree works fine on bytes, the fd based does not.
if isinstance(path, bytes):
path = os.fsdecode(path)
# Note: To guard against symlink races, we use the standard
# lstat()/open()/fstat() trick.
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())
else:
try:
# symlinks to directories are forbidden, see bug #1669
raise OSError("Cannot call rmtree on a symbolic link")
except OSError:
onerror(os.path.islink, path, sys.exc_info())
finally:
os.close(fd)
else:
return _rmtree_unsafe(path, onerror) # Allow introspection of whether or not the hardening against symlink
# attacks is supported on the current platform
rmtree.avoids_symlink_attacks = _use_fd_functions

查看源代码

9  shutil.move(src, dst)    #递归的移动文件

def move(src, dst):
"""Recursively move a file or directory to another location. This is
similar to the Unix "mv" command. Return the file or directory's
destination. If the destination is a directory or a symlink to a directory, the source
is moved inside the directory. The destination path must not already
exist. If the destination already exists but is not a directory, it may be
overwritten depending on os.rename() semantics. If the destination is on our current filesystem, then rename() is used.
Otherwise, src is copied to the destination and then removed. Symlinks are
recreated under the new name if os.rename() fails because of cross
filesystem renames. A lot more could be done here... A look at a mv.c shows a lot of
the issues this implementation glosses over. """
real_dst = dst
if os.path.isdir(dst):
if _samefile(src, dst):
# We might be on a case insensitive filesystem,
# perform the rename anyway.
os.rename(src, dst)
return 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, symlinks=True)
rmtree(src)
else:
copy2(src, real_dst)
os.unlink(src)
return real_dst

查看源代码

10  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". 'root_dir' is a directory that will be the root directory of the
archive; ie. we typically chdir into 'root_dir' before creating the
archive. 'base_dir' is the directory where we start archiving from;
ie. '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. Returns the name of the archive file. 'owner' and 'group' are used when creating a tar archive. By default,
uses the current owner and group.
"""
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 = {'dry_run': dry_run, '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

查看源代码

base_name:    压缩打包后的文件名或者路径名

format:          压缩或者打包格式    "zip", "tar", "bztar"or "gztar"

root_dir :         将哪个目录或者文件打包(也就是源文件)

>>> shutil.make_archive('tarball','gztar',root_dir='copytree_test')

[root@slyoyo python_test]# ls -l
total 12
drwxr-xr-x. 3 root root 4096 May 14 19:36 copytree_copy
drwxr-xr-x. 3 root root 4096 May 14 19:36 copytree_test
-rw-r--r--. 1 root root 0 May 14 21:12 tarball.tar.gz
-rw-r--r--. 1 python python 79 May 14 05:17 test1
-rw-r--r--. 1 root root 0 May 14 19:10 test2

实例

python之shutil模块详解的更多相关文章

  1. python之OS模块详解

    python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...

  2. python之sys模块详解

    python之sys模块详解 sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传 ...

  3. python中threading模块详解(一)

    python中threading模块详解(一) 来源 http://blog.chinaunix.net/uid-27571599-id-3484048.html threading提供了一个比thr ...

  4. Python中time模块详解

    Python中time模块详解 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. ...

  5. Python的logging模块详解

          Python的logging模块详解 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.日志级别 日志级别指的是产生的日志的事件的严重程度. 设置一个级别后,严重程度 ...

  6. python标准库介绍——16 shutil模块详解

    ``shutil`` 实用模块包含了一些用于复制文件和文件夹的函数. [Example 2-4 #eg-2-4] 中使用的 ``copy`` 函数使用和 Unix 下 ``cp`` 命令基本相同的方式 ...

  7. python中常用模块详解二

    log模块的讲解 Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适: logger提供了应用程序可以直接使用的接口API: handler将(logger创建的 ...

  8. python中常用模块详解一

    1.time 模块 import time s = time.localtime() # 把时间转化成格式化的时间,通过. 取得里面的年月日等 struct_time 格式 time.struct_t ...

  9. python的re模块详解

    一.正则表达式的特殊字符介绍 正则表达式 ^ 匹配行首 $ 匹配行尾 . 任意单个字符 [] 匹配包含在中括号中的任意字符 [^] 匹配包含在中括号中的字符之外的字符 [-] 匹配指定范围的任意单个字 ...

随机推荐

  1. Aria2 无限制下载神器

    Aria2 是一款免费开源跨平台且不限速的多线程下载软件,Aria2的优点是速度快.体积小.资源占用少:支持 HTTP / FTP / BT / Magnet 磁力链接等类型的文件下载:支持 Win. ...

  2. 新手指南:Linux上vi(vim)编辑器使用教程

    vi(vim)是上Linux非常常用的编辑器,很多Linux发行版都默认安装了vi(vim).vi(vim)命令繁多但是如果使用灵活之后将会大大提高效率.vi是“visual interface”的缩 ...

  3. css-table属性运用

    最近在工作中遇到了一些不常用的布局,很多使用 CSS table 属性,并结合 ::before,::after 伪元素完成了,使得 HTML 的结构相对更简单,更具有语义性.当 HTML 结构越清晰 ...

  4. 4-1 R语言函数 lapply

    #lapply函数 #可以循环处理列表中的每一个元素 #lapply(参数):lapply(列表,函数/函数名,其他参数) #总是返回一个列表 #sapply:简化结果 #结果列表元素长度均为1,返回 ...

  5. AOP:选择正确的时机进行编织

    在本文中,我们将采用三种重要的实现的例子,来实践本文提出的概念.这三种 AOP 实现是 AspectJ,Spring 和 JBoss.通过比较他们在 Weave 时机方面的不同,来获得对于如何选择 W ...

  6. 【JavaScript】赛码网前端笔试本地环境搭建

    参考:https://hoofoo.me/article/2017-04-11/%E8%B5%9B%E7%A0%81%E7%BD%91%E5%89%8D%E7%AB%AF%E7%AC%94%E8%AF ...

  7. Core WebAPI 入门

    官方文档地址 https://docs.microsoft.com/zh-cn/aspnet/?view=aspnetcore-2.2#pivot=core 使用 ASP.NET Core 构建 We ...

  8. [转]TortoiseSVN客户端重新设置用户名和密码

    在第一次使用TortoiseSVN从服务器CheckOut的时候,会要求输入用户名和密码,这时输入框下面有个选项是保存认证信息,如果选了这个选项,那么以后就不用每次都输入一遍用户名密码了. 不过,如果 ...

  9. $python爬虫系列(2)—— requests和BeautifulSoup库的基本用法

    本文主要介绍python爬虫的两大利器:requests和BeautifulSoup库的基本用法. 1. 安装requests和BeautifulSoup库 可以通过3种方式安装: easy_inst ...

  10. jQuery插件,判断鼠标的移入移出方向

    今天用jQuery封装了一个简单的插件,判断鼠标的移入移出方向,以后的项目中可能还会遇到这样一个简单的效果,就记录下来吧! 先看结构和样式: <!DOCTYPE html> <htm ...