python sys与shutil模块

<!DOCTYPE html>


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

转载于:https://www.cnblogs.com/dcotorbool/p/7007820.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值