python sys与shutil模块

sys与shutil模块

sys模块与shutil模块

sys模块


import sys #读入sys
sys.argv 命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0)
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
sys.stdout.write('please:')
val = sys.stdin.readline()[:-1]

使用sys.argv

import sys
print(sys.argv)
输入python systest.py 1 2 3 4 5
输出['systest.py', '1', '2', '3', '4', '5']

shutil模块 就是copy文件用的 高级的 文件、文件夹、压缩包 处理模块

copyfileobj方法的使用

import shutil
f1=open('123.txt',encoding='utf-8')
f2=open('321.txt','w',encoding='utf-8')
shutil.copyfileobj(f1,f2)

copyfile方法,此方法也是调用copyfileobj完成的复制

import shutil
shutil.copyfile('123.txt','213.txt')

shutil.copymode(src, dst)仅拷贝权限。内容、组、用户均不变

def copymode(src, dst):
"""Copy mode bits from src to dst""" if hasattr(os, 'chmod'):
st = os.stat(src)
mode = stat.S_IMODE(st.st_mode)#只复制了权限
os.chmod(dst, mode)

shutil.copystat(src, dst)拷贝状态的信息,包括:mode bits, atime, mtime, flags

def copystat(src, dst):
"""Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""
st = os.stat(src)
mode = stat.S_IMODE(st.st_mode)
if hasattr(os, 'utime'):
os.utime(dst, (st.st_atime, st.st_mtime))
if hasattr(os, 'chmod'):
os.chmod(dst, mode)
if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):
try:
os.chflags(dst, st.st_flags)
except OSError, why:
for err in 'EOPNOTSUPP', 'ENOTSUP':
if hasattr(errno, err) and why.erro == getattr(errno, err):
break
else:
raise

使用

import shutil
import os   
print('123.txt的属性',os.stat('123.txt'))
print('321.txt的属性',os.stat('321.txt'))
print('-----------------------------')
shutil.copystat('123.txt','321.txt')
print('123.txt的属性',os.stat('123.txt'))
print('321.txt的属性',os.stat('321.txt'))
输出: 123.txt的属性 os.stat_result(st_mode=33206, st_ino=38843546786354155, st_dev=1178654058, st_nlink=1, st_uid=0, st_gid=0, st_size=104, st_atime=1497404453, st_mtime=1497404453, st_ctime=1497404442)
321.txt的属性 os.stat_result(st_mode=33206, st_ino=22517998137141947, st_dev=1178654058, st_nlink=1, st_uid=0, st_gid=0, st_size=121, st_atime=1497405718, st_mtime=1497405718, st_ctime=1497404522)
-----------------------------
123.txt的属性 os.stat_result(st_mode=33206, st_ino=38843546786354155, st_dev=1178654058, st_nlink=1, st_uid=0, st_gid=0, st_size=104, st_atime=1497404453, st_mtime=1497404453, st_ctime=1497404442)
321.txt的属性 os.stat_result(st_mode=33206, st_ino=22517998137141947, st_dev=1178654058, st_nlink=1, st_uid=0, st_gid=0, st_size=121, st_atime=1497404453, st_mtime=1497404453, st_ctime=1497404522)

shutil.copy(src, dst)拷贝文件和权限,源码里有两个方法,copyfile和copymode

def copy(src, dst):
"""Copy data and mode bits ("cp src dst").

The destination may be a directory.

"""
if os.path.isdir(dst):

dst = os.path.join(dst, os.path.basename(src))

copyfile(src, dst)

copymode(src, dst)

shutil.copy2(src, dst)拷贝文件和状态信息

def copy2(src, dst):
"""Copy data and all stat info ("cp -p src dst").

The destination may be a directory.

"""
if os.path.isdir(dst):

dst = os.path.join(dst, os.path.basename(src))

copyfile(src, dst)

copystat(src, dst)

shutil.copytree(src, dst, symlinks=False, ignore=None) 递归的去拷贝文件, 例如:copytree(source, destination, ignore=ignore_patterns ('.pyc', 'tmp'))

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

def copytree(src, dst, symlinks=False, ignore=None): """Recursively copy a directory tree using copy2().

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.

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.

XXX Consider this example code rather than the ultimate tool.

"""
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 symlinks and os.path.islink(srcname):
linkto = os.readlink(srcname)
os.symlink(linkto, dstname)
elif os.path.isdir(srcname):
copytree(srcname, dstname, symlinks, ignore)
else:
# Will raise a SpecialFileError for unsupported file types
copy2(srcname, dstname)
# catch the Error from the recursive copytree so that we can
# continue with other files
except Error, err:
errors.extend(err.args[0])
except EnvironmentError, why:
errors.append((srcname, dstname, str(why)))
try:
copystat(src, dst)
except OSError, why:
if WindowsError is not None and isinstance(why, WindowsError):
# Copying file access times may fail on Windows
pass
else:
errors.append((src, dst, str(why)))
if errors:
raise Error, errors

shutil.rmtree(path[, ignore_errors[, onerror]]) 递归的去删除文件

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 os.listdir, os.remove, or os.rmdir;
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
try:
if os.path.islink(path):
# 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())
# can't continue even if onerror hook returns
return
names = []
try:
names = os.listdir(path)
except os.error, err:
onerror(os.listdir, path, sys.exc_info())
for name in names:
fullname = os.path.join(path, name)
try:
mode = os.lstat(fullname).st_mode
except os.error:
mode = 0
if stat.S_ISDIR(mode):
rmtree(fullname, ignore_errors, onerror)
else:
try:
os.remove(fullname)
except os.error, err:
onerror(os.remove, fullname, sys.exc_info())
try:
os.rmdir(path)
except os.error:
onerror(os.rmdir, path, sys.exc_info())

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.

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.
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.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)

shutil.makearchive(basename, format,...) 创建压缩包并返回文件路径,例如:zip、tar

  1. base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径, 如:www =>保存至当前路径 如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/
  2. format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
  3. root_dir: 要压缩的文件夹路径(默认当前目录)
  4. owner: 用户,默认当前用户
  5. group: 组,默认当前组
  6. logger: 用于记录日志,通常是logging.Logger对象

    import shutil shutil.make_archive('hello','zip',r'C:\Users\My\PycharmProjects\ATM\wjtest')

源码

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

shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:

#zip压缩
import zipfile
z=zipfile.ZipFile('hello.zip','w')
z.write('name.xml')
z.write('name2.xml')
z.close()
# 解压
z = zipfile.ZipFile('hello.zip', 'r')
z.extractall()
z.close()

import tarfile

tar压缩

tar = tarfile.open('your.tar','w')
tar.add('/Users/wupeiqi/PycharmProjects/bbs2.zip', arcname='bbs2.zip')
tar.add('/Users/wupeiqi/PycharmProjects/cmdb.zip', arcname='cmdb.zip')
tar.close()

解压

tar = tarfile.open('your.tar','r')
tar.extractall() # 可设置解压地址
tar.close()

posted @ 2017-06-14 11:14  Doctor_Bool  阅读(300)  评论(0编辑  收藏  举报