• python运维常用相关模块


                            python运维常用相关模块

                                          作者:尹正杰

    版权声明:原创作品,谢绝转载!否则将追究法律责任。 

     

    一.模块的分类

    模块,用一砣代码实现了某个功能的代码集合。 

    类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。

    如:os 是系统相关的模块;file是文件操作相关的模块

    模块分为三种:

      1>.自定义模块:自定义的模块,顾名思义,就是你自己写的python程序,我们知道python的代码都存在一个以".py"结尾的文件中的,我们这样命名一个python脚本,吧后缀去掉就是模块名称,这个就是自定义模块,我举个例子:我写了一个yinzhengjie.py的文件。里面的内容我们可以忽略,如果我们要导入这个模块的话直接导入yinzhengjie这个模块名称就好了;

      2>.内置模块:那么问题来了,我们学的cha(),id()等等所有的内置函数是模块吗?答案是否定的!不是!对内置函数不是内置模块,他们只是python解释器自带的一些功能,那么什么是内置模块呢?一会我会再我的博客中提到一些常用的内置模块;

      3>.开源模块:这个就很好解释了,python语言的官网提供了一个供应开发人员上传你的代码到服务器上(https://pypi.python.org/pypi),然后客户端只要在命令行中输入安装命令就可以随意的在shell或者cmd的python解释器中调用这个第三方模块,比如:pip install paramiko.

    二.内置模块解析:

     1.OS模块详解

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import os
     7 #1.获取当前工作目录,即当前python脚本工作的目录路径
     8 print(os.getcwd())
     9 #2.改变当前脚本工作目录;相当于shell下cd,记住,这个是没有返回值的哟!
    10 print(os.chdir(r"D:pythondaimaDAY1"))
    11 #3.返回当前目录: ('.')
    12 print(os.curdir)
    13 #4.获取当前目录的父目录字符串名:('..')
    14 print(os.pardir)
    15 #5.可生成多层递归目录(创建目录),生产完毕后返回一个None值
    16 print(os.makedirs("D:pythondaimaDAY10"))
    17 #6.若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推(和上面的相反,就是删除目录。)
    18 print(os.removedirs("D:pythondaimaDAY10"))
    19 #7.生成单级目录;相当于shell中mkdir dirname,如果当前目录已经存在改目录就会报错!
    20 print(os.mkdir("DAY10"))
    21 #8.删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname,如果当前目录没有改目录就会报错!
    22 print(os.rmdir("DAY10"))
    23 #9.列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    24 print(os.listdir("D:pythondaima"))
    25 #10.删除一个文件
    26 # os.remove("locked.txt")
    27 #11.重命名文件/目录
    28 # os.rename("oldname","newname")
    29 #12.os.stat('path/filename')  获取文件/目录信息
    30 print(os.stat("D:pythondaimaDAY4"))
    31 #13.输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
    32 print(os.sep)
    33 #14.输出当前平台使用的行终止符,win下为"
    ",Linux下为"
    "
    34 print(os.linesep)
    35 #15.输出用于分割文件路径的字符串
    36 print(os.pathsep)
    37 #16.输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
    38 print(os.name)
    39 #17.运行shell或者windows命令,直接显示命令的输出结果,可以将这个数据存放在一个变量中哟
    40 # print(os.system("dir"))
    41 #18.返回path规范化的绝对路径
    42 print(os.path.abspath("user_info.txt"))
    43 #19.将path分割成目录和文件名二元组返回
    44 print(os.path.split(r"D:pythondaimaDAY1user_info.txt"))
    45 #20.返回path的目录。其实就是os.path.split(path)的第一个元素
    46 print(os.path.dirname(r"D:pythondaimaDAY1user_info.txt"))
    47 #21.os.path.basename(path)  返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素
    48 print(os.path.basename(r"D:pythondaimaDAY1user_info.txt"))
    49 #22.os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
    50 print(os.path.exists(r"D:pythondaimaDAY1user_info.txt"))
    51 #23.os.path.isabs(path)  如果path是绝对路径,返回True
    52 print(os.path.isabs(r"D:pythondaimaDAY1user_info.txt"))
    53 #24.os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
    54 print(os.path.isfile(r"D:pythondaimaDAY1user_info.txt"))
    55 #25.os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
    56 print(os.path.isdir(r"D:pythondaimaDAY1user_info.txt"))
    57 #26.os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
    58 print(os.path.join(r"user_info.txt",r"D:pythondaimaDAY1user_info.txt"))
    59 #27.os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
    60 print(os.path.getatime(r"D:pythondaimaDAY1user_info.txt"))
    61 #28.os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
    62 print(os.path.getmtime(r"D:pythondaimaDAY1user_info.txt"))
    63 '''
    64 更多关于os模块的使用方法请参考:https://docs.python.org/2/library/os.html?highlight=os#module-os
    65 '''
    66 
    67 
    68 #以上代码执行结果如下:
    69 D:pythondaimaDAY4
    70 None
    71 .
    72 ..
    73 None
    74 None
    75 None
    76 None
    77 ['.idea', 'DAY1', 'DAY2', 'DAY3', 'DAY4', 'DAY5', '__pycache__']
    78 os.stat_result(st_mode=16895, st_ino=22799473113577966, st_dev=839182139, st_nlink=1, st_uid=0, st_gid=0, st_size=4096, st_atime=1487743397, st_mtime=1487743397, st_ctime=1486692902)
    79 
    80 
    81 
    82 ;
    83 nt
    84 D:pythondaimaDAY1user_info.txt
    85 ('D:\python\daima\DAY1', 'user_info.txt')
    86 D:pythondaimaDAY1
    87 user_info.txt
    88 True
    89 True
    90 True
    91 False
    92 D:pythondaimaDAY1user_info.txt
    93 1483869109.7747889
    94 1483869109.7758367
    os模块常用方法详解

     2.sys模块常用方法

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import sys
     7 #1.获取Python解释程序的版本信息
     8 print(sys.version)
     9 #2.返回操作系统平台名称
    10 print(sys.platform)
    11 #3.返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    12 print(sys.path)
    13 #4.退出程序,正常退出时exit(0),如果不写数字的话,默认就是0
    14 # print(sys.exit(100))
    15 #5.命令行参数List,第一个元素是程序本身路径
    16 # path_info = sys.argv[1]
    17 #6.显示当前系统最大的Int值
    18 print(sys.maxsize)
    19 
    20 '''
    21 更多使用方法请参考:https://docs.python.org/2/library/sys.html?highlight=sys#module-sys
    22 '''
    23 
    24 
    25 #以上代码执行结果如下:
    26 
    27 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)]
    28 win32
    29 ['D:\python\daima\DAY4', 'D:\python\daima', 'C:\Users\yzj\AppData\Local\Programs\Python\Python35-32\python35.zip', 'C:\Users\yzj\AppData\Local\Programs\Python\Python35-32\DLLs', 'C:\Users\yzj\AppData\Local\Programs\Python\Python35-32\lib', 'C:\Users\yzj\AppData\Local\Programs\Python\Python35-32', 'C:\Users\yzj\AppData\Local\Programs\Python\Python35-32\lib\site-packages']
    30 2147483647
    sys模块常用方法详解

    3.json和pickle模块详解

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import pickle
     7 '''
     8 pickle:
     9     1.>用于python特有的类型 和 python的数据类型间进行转换
    10     2.>pickle模块提供了四个功能:dumps、dump、loads、load.
    11     补充说明:将数据通过特殊的形式转换成只有python解释器识别的字符串,这个过程我们叫做序列化,而把哪些python能够识别的字符串转换成我们能看懂的叫做反序列化。
    12 '''
    13 data_info = {"name":"尹正杰","password":"123"}
    14 #1.将数据通过特殊的形式转换为只有python语言知识的字符串并写入文件
    15 # pickle_str = pickle.dumps(data_info)
    16 # print(pickle_str)
    17 # f = open("test.txt","wb")
    18 # f.write(pickle_str)
    19 #2.上面的写入文件的方法也可以这么玩,看起来更简单
    20 # with open("test_1.txt","wb") as fb:
    21 #     pickle.dump(data_info,fb)
    22 #我们知道将数据存入文件,那么我们怎么把存入文件的东西读出来呢?
    23 #方法一:
    24 # f = open("test_1.txt","rb")
    25 # print(pickle.loads(f.read()))
    26 #方法二:
    27 f = open("test_1.txt","rb")
    28 print(pickle.load(f))
    python自带pickle模块用法
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import json
     7 '''
     8 用于序列化的两个模块
     9     1>.json:用于字符串 和 python数据类型间进行转换
    10     2>.pickle:用于python特有的类型和python的数据类型间进行转换
    11     json模块提供了四个功能:dumps、dump、loads、load
    12     pickle模块提供了四个功能:dumps、dump、loads、load
    13 '''
    14 accounts = {
    15     "id":521,
    16     "name":"yinzhengjie",
    17     "banlance":"9000"
    18 }
    19 #存数据方式一:
    20 # f = open(r"D:pythondaimaDAY4	est_2.txt","w")
    21 # json_str = json.dumps(accounts)
    22 # f.write(json_str)
    23 #存数据方式二:
    24 # with open(r"D:pythondaimaDAY4	est_2.txt","w") as fp:
    25 #     json.dump(accounts,fp)
    26 #读取数据的方法一:
    27 # f = open("test_2.txt","r")
    28 # print(json.loads(f.read()))
    29 #方法二:
    30 f = open("test_2.txt","r")
    31 print(json.load(f))
    Python自带的json模块用法

    对比json和pickle的异同:

         1>.相同点:都是用于系列化和反序列化的模块。

      2>.不同点:json是在所有语言都通用的数据存储格式,而pickle是仅仅只有python语言独有的存储格式。

    4.time模块与datetime模块详解

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import time
     7 #1.测量处理器运算时间,不包括sleep时间,不稳定,mac上测不出来
     8 print(time.process_time())
     9 #2.返回与utc时间的时间差,以秒计算
    10 print(time.altzone)
    11 #3.返回默认时间格式
    12 print(time.asctime())
    13 #4.返回本地时间的struct_time对象格式
    14 print(time.localtime())
    15 #5.返回utc时间的struc时间对象格式
    16 print(time.gmtime(time.time()-800000))
    17 #6.返回本地时间格式,
    18 print(time.asctime(time.localtime()))
    19 #7.返回时间格式,同上
    20 print(time.ctime())
    21 #8.将日期字符串转成struct时间对象格式
    22 string_2_struct = time.strptime("2016/05/22","%Y/%m/%d")
    23 print(string_2_struct)
    24 #9.将struct时间对象转成时间戳
    25 struct_2_stamp = time.mktime(string_2_struct)
    26 print(struct_2_stamp)
    27 #10.将utc时间戳转换成struct_time格式
    28 print(time.gmtime(time.time()-86640))
    29 #11.将utc struct_time格式转成指定的字符串格式
    30 print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()))
    time模块演示
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import time,datetime
     7 #1.打印当前系统时间
     8 print(datetime.datetime.now())
     9 #2.时间戳直接转成日期格式如:2017-02-22
    10 print(datetime.date.fromtimestamp(time.time()))
    11 #3.当前时间+3天
    12 print(datetime.datetime.now() + datetime.timedelta(3))
    13 #4.当前时间-3天
    14 print(datetime.datetime.now() + datetime.timedelta(-3))
    15 #5.当前时间+3小时
    16 print(datetime.datetime.now() + datetime.timedelta(hours=3))
    17 #6.当前时间+30分
    18 print(datetime.datetime.now() + datetime.timedelta(minutes=30))
    19 #7.时间替换
    20 c_time  = datetime.datetime.now()
    21 print(c_time.replace(minute=3,hour=2))
    datetime模块用法

    关于时间的一个转换流程图:

    测试代码如下:

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import time
     7 #1.将日期转换成struct_time格式,会以一个tuple的形式打印出来
     8 # struct_time = time.strptime("2017/2/22","%Y/%m/%d") #注意分割的符号要保持一致哟,我这里分割的符号是“/”
     9 struct_time = time.strptime("2017-2-22 17:29:30","%Y-%m-%d %H:%M:%S")  #ye ky 注意分割的符号要保持一致哟,我这里分割的符号是“-”
    10 print(struct_time)
    11 #2.将struct_time格式转换成时间戳的形式
    12 stamp_time = time.mktime(struct_time)
    13 print(stamp_time)
    14 #3.将时间戳的形式,转换成日期格式
    15 date_time  = time.gmtime(stamp_time)
    16 print(date_time)
    17 print(time.strftime("%Y-%m-%d %H:%M:%S",date_time))

     关于参数的详细说明如下:

    DirectiveMeaningNotes
    %a Locale’s abbreviated weekday name.  
    %A Locale’s full weekday name.  
    %b Locale’s abbreviated month name.  
    %B Locale’s full month name.  
    %c Locale’s appropriate date and time representation.  
    %d Day of the month as a decimal number [01,31].  
    %H Hour (24-hour clock) as a decimal number [00,23].  
    %I Hour (12-hour clock) as a decimal number [01,12].  
    %j Day of the year as a decimal number [001,366].  
    %m Month as a decimal number [01,12].  
    %M Minute as a decimal number [00,59].  
    %p Locale’s equivalent of either AM or PM. (1)
    %S Second as a decimal number [00,61]. (2)
    %U Week number of the year (Sunday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Sunday are considered to be in week 0. (3)
    %w Weekday as a decimal number [0(Sunday),6].  
    %W Week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0. (3)
    %x Locale’s appropriate date representation.  
    %X Locale’s appropriate time representation.  
    %y Year without century as a decimal number [00,99].  
    %Y Year with century as a decimal number.  
    %z Time zone offset indicating a positive or negative time difference from UTC/GMT of the form +HHMM or -HHMM, where H represents decimal hour digits and M represents decimal minute digits [-23:59, +23:59].  
    %Z Time zone name (no characters if no time zone exists).  
    %% A literal '%' character.

    5.random模块详解

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import random
     7 '''
     8 random:
     9         是用来生成随机数字的。
    10 '''
    11 #举例子:
    12 print(random.random())
    13 print(random.randint(1,20))
    14 print(random.randrange(1,10))
    15 '''
    16 random 都有哪些应用呢?
    17 '''
    18 #生成随机验证码,版本一:
    19 checkcode = ''
    20 for i in range(6):  #修改后面的数字表示随机生成的数字个数,因为要循环6次
    21     current = random.randrange(0,4)
    22     if current != i:
    23         temp = chr(random.randint(65,90))
    24     else:
    25         temp = random.randint(0,9)
    26     checkcode += str(temp)
    27 print(checkcode)
    28 #生成随机验证码,版本二
    29 import string
    30 source = string.digits + string.ascii_lowercase
    31 print("".join(random.sample(source,6)))  #修改后面的数字表示随机生成的数字个数
    random常见方法及应用

    6.logging模块

       很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug()info()warning()error() and critical() 5个级别,从左往右依次增加告警级别,下面我们看一下怎么用。

        看一下这几个日志级别分别代表什么意思

    LevelWhen it’s used
    DEBUG Detailed information, typically of interest only when diagnosing problems.
    INFO Confirmation that things are working as expected.
    WARNING An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected.
    ERROR Due to a more serious problem, the software has not been able to perform some function.
    CRITICAL A serious error, indicating that the program itself may be unable to continue running.

      日志格式

    %(name)s

    Logger的名字

    %(levelno)s

    数字形式的日志级别

    %(levelname)s

    文本形式的日志级别

    %(pathname)s

    调用日志输出函数的模块的完整路径名,可能没有

    %(filename)s

    调用日志输出函数的模块的文件名

    %(module)s

    调用日志输出函数的模块名

    %(funcName)s

    调用日志输出函数的函数名

    %(lineno)d

    调用日志输出函数的语句所在的代码行

    %(created)f

    当前时间,用UNIX标准的表示时间的浮 点数表示

    %(relativeCreated)d

    输出日志信息时的,自Logger创建以 来的毫秒数

    %(asctime)s

    字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

    %(thread)d

    线程ID。可能没有

    %(threadName)s

    线程名。可能没有

    %(process)d

    进程ID。可能没有

    %(message)s

    用户输出的消息

    A.简单的logging模块案例演示:

    1>.初探logging模块:

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import logging
     7 logging.warning("user [尹正杰] attempted wrong password more than 3 times")
     8 logging.critical("server is down")
     9 
    10 
    11 以上代码执行结果如下:
    12 WARNING:root:user [尹正杰] attempted wrong password more than 3 times
    13 CRITICAL:root:server is down

    2>.如果想把日志写到文件里,也很简单:

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import logging
     7 logging.basicConfig(filename='yinzhengjie.log', level=logging.INFO)
     8 logging.debug('This message should go to the log file')
     9 logging.info('So should this')
    10 logging.warning('And this, too')
    11 
    12 '''
    13 补充说明:
    14      logging.basicConfig中的参数level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子,第一条日志是不会被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。
    15 '''
    16 
    17 
    18 #查看'yinzhengjie.log'文件内容如下:
    19 INFO:root:So should this
    20 WARNING:root:And this, too

    B.如果想同时把log打印在屏幕和文件日志里,就需要了解一点复杂的知识了:

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 '''
     7 Python使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:
     8     1>.logger提供了应用程序可以直接使用的接口;
     9     2>.handler将(logger创建的)日志记录发送到合适的目的输出;
    10     3>.filter提供了细度设备来决定输出哪条日志记录;
    11     4>.formatter决定日志记录的最终输出格式。
    12 '''
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 '''
     7 Python使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:
     8     1>.logger提供了应用程序可以直接使用的接口;
     9     2>.handler将(logger创建的)日志记录发送到合适的目的输出;
    10     3>.filter提供了细度设备来决定输出哪条日志记录;
    11     4>.formatter决定日志记录的最终输出格式。
    12 '''
    13 
    14 
    15 #logger
    16 '''
    17     每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名.
    18 #1>.比如聊天工具的图形界面模块可以这样获得它的Logger:
    19 LOG=logging.getLogger(”chat.gui”)
    20 #2>.而核心模块可以这样:
    21 LOG=logging.getLogger(”chat.kernel”)
    22 #3>.指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
    23 Logger.setLevel(lel)
    24 #4>.添加或删除指定的filter
    25 Logger.addFilter(filt)、Logger.removeFilter(filt)
    26 #5>.增加或删除指定的handler
    27 Logger.addHandler(hdlr)、Logger.removeHandler(hdlr)
    28 #6>.可以设置的日志级别
    29 Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()
    30 '''
    31 
    32 
    33 #handler
    34 '''
    35         handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
    36 #1>.指定被处理的信息级别,低于lel级别的信息将被忽略
    37 Handler.setLevel(lel)
    38 #2>.给这个handler选择一个格式
    39 Handler.setFormatter()
    40 #3>.新增或删除一个filter对象
    41 Handler.addFilter(filt)、Handler.removeFilter(filt)
    42         每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:
    43 #1>.logging.StreamHandler
    44         使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:StreamHandler([strm]),其中strm参数是一个文件对象。默认是sys.stderr
    45 2) logging.FileHandler
    46         和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:FileHandler(filename[,mode]),filename是文件名,必须指定一个文件名。mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。
    47 3) logging.handlers.RotatingFileHandler
    48         这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]]),其中filename和mode两个参数和FileHandler一样。maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
    49 4) logging.handlers.TimedRotatingFileHandler
    50         这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]),其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义,interval是时间间隔。when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:(S[秒],M[分],H[小时],D[天],W[每星期(interval==0时代表星期一)],midnight[每天凌晨]
    51 '''
    常用的功能介绍
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import logging
     7 # create logger
     8 logger = logging.getLogger('TEST-LOG')  #定义报警的标题
     9 logger.setLevel(logging.DEBUG)  #设置在屏幕中打印的报警级别和写入文件的文件的最低级别这个相当于总开关,下面2个调试都得在这基础之上对告警级别做处理。
    10 # create console handler and set level to debug
    11 ch = logging.StreamHandler()
    12 ch.setLevel(logging.DEBUG)  #设置在屏幕中打印的报警级别,(优先权没有第一个权限高)
    13 # create file handler and set level to warning  #创建文件处理程序并设置告警级别。
    14 fh = logging.FileHandler("access.log")  #定义保存日志的文件
    15 fh.setLevel(logging.WARNING)   #定义将报警信息写入文件中的级别(优先权没有第一个权限高))
    16 # create formatter  #定义输出格式
    17 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    18 # add formatter to ch and fh  #添加格式花输出
    19 ch.setFormatter(formatter)
    20 fh.setFormatter(formatter)
    21 # add ch and fh to logger  #添加记录器
    22 logger.addHandler(ch)
    23 logger.addHandler(fh)
    24 # 'application' code #定义各种报警级别输出的内容。
    25 logger.debug('debug message')
    26 logger.info('info message')
    27 logger.warn('warn message')
    28 logger.error('error message')
    29 logger.critical('critical message')
    30 
    31 #屏幕输入内容如下:
    32 2017-02-23 10:08:28,184 - TEST-LOG - DEBUG - debug message
    33 2017-02-23 10:08:28,185 - TEST-LOG - INFO - info message
    34 2017-02-23 10:08:28,185 - TEST-LOG - WARNING - warn message
    35 2017-02-23 10:08:28,185 - TEST-LOG - ERROR - error message
    36 2017-02-23 10:08:28,185 - TEST-LOG - CRITICAL - critical message
    37 
    38 
    39 #文件存入内容如下:
    40 2017-02-23 10:08:28,185 - TEST-LOG - WARNING - warn message
    41 2017-02-23 10:08:28,185 - TEST-LOG - ERROR - error message
    42 2017-02-23 10:08:28,185 - TEST-LOG - CRITICAL - critical message
    控制报警级别的输出案例
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import logging
     7 from logging import handlers
     8 logger = logging.getLogger(__name__)
     9 log_file = "timelog.log"
    10 #fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3)
    11 fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3) #filename定义将信息输入到指定的文件,when指定单位是s(秒),interval是时间间隔的频率,单位是when所指定的哟(所以,你可以理解频率是5s);backupCount表示备份的文件个数,我这里是指定的3个文件。
    12 formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s')  #定义输出格式
    13 fh.setFormatter(formatter) #添加格式化输出
    14 logger.addHandler(fh)
    15 logger.warning("test1")
    16 logger.warning("test2")
    17 logger.warning("test3")
    18 logger.warning("test4")
    按照时间自动截断并保存指定文件个数的案例

    7.shutil模块3

        改模块可以处理高级的 文件、文件夹、压缩包

    1>.将文件内容拷贝到另一个文件中,可以部分内容

    1 def copyfileobj(fsrc, fdst, length=16*1024): #需要制定一个源文件,目标文件,以及每次读取的长度.
    2     """copy data from file-like object fsrc to file-like object fdst"""
    3     while 1:
    4         buf = fsrc.read(length)
    5         if not buf:
    6             break
    7         fdst.write(buf)
    shutil.copyfileobj函数的源代码
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import shutil
    7 f_1 = open("file_1","r+",encoding="utf-8")
    8 f_2 = open("file_2","a+",encoding="utf-8") #如果这里是“r+”的方式打开的话那么在下面调用copyfileobj函数的时候,这个文件会被重定向的哟!(也就是之前的内容会被覆盖掉)
    9 shutil.copyfileobj(f_1,f_2)  #将f_1文件的内容追加到f_2文件中.
    调用方法展示

    2>.拷贝文件

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 def copyfile(src, dst):
     7     """Copy data from src to dst"""
     8     if _samefile(src, dst):
     9         raise Error("`%s` and `%s` are the same file" % (src, dst))
    10 
    11     for fn in [src, dst]:
    12         try:
    13             st = os.stat(fn)
    14         except OSError:
    15             # File most likely does not exist
    16             pass
    17         else:
    18             # XXX What about other special files? (sockets, devices...)
    19             if stat.S_ISFIFO(st.st_mode):
    20                 raise SpecialFileError("`%s` is a named pipe" % fn)
    21 
    22     with open(src, 'rb') as fsrc:
    23         with open(dst, 'wb') as fdst:
    24             copyfileobj(fsrc, fdst)
    shutil.copyfile函数的源代码
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import shutil
    7 shutil.copyfile("file_1","file_2") #直接写源文件和目标文件,不需要像上面那样费劲的打开一个文件了,如果没有文件就创建一个,如果有的话就会直接覆盖源文件的内容有哟
    调用方法展示

    3>.仅拷贝权限。内容、组、用户均不变

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 def copymode(src, dst):
     7     """Copy mode bits from src to dst"""
     8     if hasattr(os, 'chmod'):
     9         st = os.stat(src)
    10         mode = stat.S_IMODE(st.st_mode)
    11         os.chmod(dst, mode)
    shutil.copymode函数的源代码
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import shutil
    7 shutil.copymode("file_1","file_3") #首先,这2个文件必须存在,仅仅拷贝的是权限!要注意哟!
    调用方法展示

    4>.拷贝状态的信息,包括:mode bits, atime, mtime, flags

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 def copystat(src, dst):
     7     """Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""
     8     st = os.stat(src)
     9     mode = stat.S_IMODE(st.st_mode)
    10     if hasattr(os, 'utime'):
    11         os.utime(dst, (st.st_atime, st.st_mtime))
    12     if hasattr(os, 'chmod'):
    13         os.chmod(dst, mode)
    14     if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):
    15         try:
    16             os.chflags(dst, st.st_flags)
    17         except OSError, why:
    18             for err in 'EOPNOTSUPP', 'ENOTSUP':
    19                 if hasattr(errno, err) and why.errno == getattr(errno, err):
    20                     break
    21             else:
    22                 raise
    shutil.copystat函数的源代码
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import shutil
    7 shutil.copystat("file_1","file_3") #将前面的状态信息拷贝给后面的文件。
    调用方法展示

    5>.拷贝文件和权限

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 def copy(src, dst):
     7     """Copy data and mode bits ("cp src dst").
     8 
     9     The destination may be a directory.
    10 
    11     """
    12     if os.path.isdir(dst):
    13         dst = os.path.join(dst, os.path.basename(src))
    14     copyfile(src, dst)
    15     copymode(src, dst)
    shutil.copy函数的源代码
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import shutil
    7 shutil.copy("file_1","file_11") #这个就是拷贝一个的内容还有权限一起拷贝
    调用方法展示

    6>.拷贝文件和状态信息

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 def copy2(src, dst):
     7     """Copy data and all stat info ("cp -p src dst").
     8 
     9     The destination may be a directory.
    10 
    11     """
    12     if os.path.isdir(dst):
    13         dst = os.path.join(dst, os.path.basename(src))
    14     copyfile(src, dst)
    15     copystat(src, dst)
    shutil.copy2函数的源代码
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import shutil
    7 shutil.copy2("file_1","file_22") #这个就是拷贝一个的内容还有状态信息也一并拷贝
    调用方法展示

     7>.递归的去拷贝文件

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 def ignore_patterns(*patterns):
     7     """Function that can be used as copytree() ignore parameter.
     8 
     9     Patterns is a sequence of glob-style patterns
    10     that are used to exclude files"""
    11     def _ignore_patterns(path, names):
    12         ignored_names = []
    13         for pattern in patterns:
    14             ignored_names.extend(fnmatch.filter(names, pattern))
    15         return set(ignored_names)
    16     return _ignore_patterns
    17 
    18 def copytree(src, dst, symlinks=False, ignore=None):
    19     """Recursively copy a directory tree using copy2().
    20 
    21     The destination directory must not already exist.
    22     If exception(s) occur, an Error is raised with a list of reasons.
    23 
    24     If the optional symlinks flag is true, symbolic links in the
    25     source tree result in symbolic links in the destination tree; if
    26     it is false, the contents of the files pointed to by symbolic
    27     links are copied.
    28 
    29     The optional ignore argument is a callable. If given, it
    30     is called with the `src` parameter, which is the directory
    31     being visited by copytree(), and `names` which is the list of
    32     `src` contents, as returned by os.listdir():
    33 
    34         callable(src, names) -> ignored_names
    35 
    36     Since copytree() is called recursively, the callable will be
    37     called once for each directory that is copied. It returns a
    38     list of names relative to the `src` directory that should
    39     not be copied.
    40 
    41     XXX Consider this example code rather than the ultimate tool.
    42 
    43     """
    44     names = os.listdir(src)
    45     if ignore is not None:
    46         ignored_names = ignore(src, names)
    47     else:
    48         ignored_names = set()
    49 
    50     os.makedirs(dst)
    51     errors = []
    52     for name in names:
    53         if name in ignored_names:
    54             continue
    55         srcname = os.path.join(src, name)
    56         dstname = os.path.join(dst, name)
    57         try:
    58             if symlinks and os.path.islink(srcname):
    59                 linkto = os.readlink(srcname)
    60                 os.symlink(linkto, dstname)
    61             elif os.path.isdir(srcname):
    62                 copytree(srcname, dstname, symlinks, ignore)
    63             else:
    64                 # Will raise a SpecialFileError for unsupported file types
    65                 copy2(srcname, dstname)
    66         # catch the Error from the recursive copytree so that we can
    67         # continue with other files
    68         except Error, err:
    69             errors.extend(err.args[0])
    70         except EnvironmentError, why:
    71             errors.append((srcname, dstname, str(why)))
    72     try:
    73         copystat(src, dst)
    74     except OSError, why:
    75         if WindowsError is not None and isinstance(why, WindowsError):
    76             # Copying file access times may fail on Windows
    77             pass
    78         else:
    79             errors.append((src, dst, str(why)))
    80     if errors:
    81         raise Error, errors
    shutil.ignore_patterns与shutil.copytree函数的源代码
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import shutil
    7 shutil.copytree(r"D:pythondaimaDAY5",r"D:pythondaimaDAY6	est",ignore=shutil.ignore_patterns("atm","*.log")) #需要输入原路径,目标路径,利用ignore函数可以对需要拷贝的东西进行过滤,我这里过滤掉源目录中所有的包含“atm”,“*log”关键字的目录或者文件。(换句话说,就是新拷贝的路径中,不包含被过滤掉的文件信息。)
    调用方法展示

    8>.递归的去删除文件

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 def rmtree(path, ignore_errors=False, onerror=None):
     7     """Recursively delete a directory tree.
     8 
     9     If ignore_errors is set, errors are ignored; otherwise, if onerror
    10     is set, it is called to handle the error with arguments (func,
    11     path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
    12     path is the argument to that function that caused it to fail; and
    13     exc_info is a tuple returned by sys.exc_info().  If ignore_errors
    14     is false and onerror is None, an exception is raised.
    15 
    16     """
    17     if ignore_errors:
    18         def onerror(*args):
    19             pass
    20     elif onerror is None:
    21         def onerror(*args):
    22             raise
    23     try:
    24         if os.path.islink(path):
    25             # symlinks to directories are forbidden, see bug #1669
    26             raise OSError("Cannot call rmtree on a symbolic link")
    27     except OSError:
    28         onerror(os.path.islink, path, sys.exc_info())
    29         # can't continue even if onerror hook returns
    30         return
    31     names = []
    32     try:
    33         names = os.listdir(path)
    34     except os.error, err:
    35         onerror(os.listdir, path, sys.exc_info())
    36     for name in names:
    37         fullname = os.path.join(path, name)
    38         try:
    39             mode = os.lstat(fullname).st_mode
    40         except os.error:
    41             mode = 0
    42         if stat.S_ISDIR(mode):
    43             rmtree(fullname, ignore_errors, onerror)
    44         else:
    45             try:
    46                 os.remove(fullname)
    47             except os.error, err:
    48                 onerror(os.remove, fullname, sys.exc_info())
    49     try:
    50         os.rmdir(path)
    51     except os.error:
    52         onerror(os.rmdir, path, sys.exc_info())
    shutil.rmtree函数的源代码
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import shutil
    7 shutil.rmtree(r"D:pythondaimaDAY6	est")
    调用方法展示

    9>.递归的去移动文件

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 def move(src, dst):
     7     """Recursively move a file or directory to another location. This is
     8     similar to the Unix "mv" command.
     9 
    10     If the destination is a directory or a symlink to a directory, the source
    11     is moved inside the directory. The destination path must not already
    12     exist.
    13 
    14     If the destination already exists but is not a directory, it may be
    15     overwritten depending on os.rename() semantics.
    16 
    17     If the destination is on our current filesystem, then rename() is used.
    18     Otherwise, src is copied to the destination and then removed.
    19     A lot more could be done here...  A look at a mv.c shows a lot of
    20     the issues this implementation glosses over.
    21 
    22     """
    23     real_dst = dst
    24     if os.path.isdir(dst):
    25         if _samefile(src, dst):
    26             # We might be on a case insensitive filesystem,
    27             # perform the rename anyway.
    28             os.rename(src, dst)
    29             return
    30 
    31         real_dst = os.path.join(dst, _basename(src))
    32         if os.path.exists(real_dst):
    33             raise Error, "Destination path '%s' already exists" % real_dst
    34     try:
    35         os.rename(src, real_dst)
    36     except OSError:
    37         if os.path.isdir(src):
    38             if _destinsrc(src, dst):
    39                 raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst)
    40             copytree(src, real_dst, symlinks=True)
    41             rmtree(src)
    42         else:
    43             copy2(src, real_dst)
    44             os.unlink(src)
    shutil.move函数源代码如下
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import shutil
    7 shutil.move(r"D:pythondaimaDAY5atm","D:pythondaimaDAY6") #前面是原路径,后面是默认路径
    调用方法展示

    10>.创建压缩包并返回文件路径,例如:zip、tar(改方法其实质上就是调用的zipfile和tarfile函数的,可以了解一下这2个函数的用法)

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import shutil
     7 shutil.make_archive("day5","zip",r"D:pythondaimaDAY5") #第一个参数需要传入归档后的文件名称,可以指定绝对路径,第二个参数表示打包的类型,tar表示归档不压缩,但是zip表示压缩,我这里用了压缩类型,第三个参数传递的是被被压缩的对象。还可以传递所属者,所属组等等。
     8 '''
     9 补充:
    10     base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    11     如:www                        =>保存至当前路径
    12     如:/Users/yinzhengjie/www =>保存至/Users/yinzhengjie/
    13     format:    压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    14     root_dir:    要压缩的文件夹路径(默认当前目录)
    15     owner:    用户,默认当前用户
    16     group:    组,默认当前组
    17     logger:    用于记录日志,通常是logging.Logger对象
    18 '''
    将目录打包的案例

    11>.zipfile用法扩充

      1 #!/usr/bin/env python
      2 #_*_coding:utf-8_*_
      3 #@author :yinzhengjie
      4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
      5 #EMAIL:y1053419035@qq.com
      6 class ZipFile(object):
      7     """ Class with methods to open, read, write, close, list zip files.
      8 
      9     z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=False)
     10 
     11     file: Either the path to the file, or a file-like object.
     12           If it is a path, the file will be opened and closed by ZipFile.
     13     mode: The mode can be either read "r", write "w" or append "a".
     14     compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib).
     15     allowZip64: if True ZipFile will create files with ZIP64 extensions when
     16                 needed, otherwise it will raise an exception when this would
     17                 be necessary.
     18 
     19     """
     20 
     21     fp = None                   # Set here since __del__ checks it
     22 
     23     def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False):
     24         """Open the ZIP file with mode read "r", write "w" or append "a"."""
     25         if mode not in ("r", "w", "a"):
     26             raise RuntimeError('ZipFile() requires mode "r", "w", or "a"')
     27 
     28         if compression == ZIP_STORED:
     29             pass
     30         elif compression == ZIP_DEFLATED:
     31             if not zlib:
     32                 raise RuntimeError,
     33                       "Compression requires the (missing) zlib module"
     34         else:
     35             raise RuntimeError, "That compression method is not supported"
     36 
     37         self._allowZip64 = allowZip64
     38         self._didModify = False
     39         self.debug = 0  # Level of printing: 0 through 3
     40         self.NameToInfo = {}    # Find file info given name
     41         self.filelist = []      # List of ZipInfo instances for archive
     42         self.compression = compression  # Method of compression
     43         self.mode = key = mode.replace('b', '')[0]
     44         self.pwd = None
     45         self._comment = ''
     46 
     47         # Check if we were passed a file-like object
     48         if isinstance(file, basestring):
     49             self._filePassed = 0
     50             self.filename = file
     51             modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'}
     52             try:
     53                 self.fp = open(file, modeDict[mode])
     54             except IOError:
     55                 if mode == 'a':
     56                     mode = key = 'w'
     57                     self.fp = open(file, modeDict[mode])
     58                 else:
     59                     raise
     60         else:
     61             self._filePassed = 1
     62             self.fp = file
     63             self.filename = getattr(file, 'name', None)
     64 
     65         try:
     66             if key == 'r':
     67                 self._RealGetContents()
     68             elif key == 'w':
     69                 # set the modified flag so central directory gets written
     70                 # even if no files are added to the archive
     71                 self._didModify = True
     72             elif key == 'a':
     73                 try:
     74                     # See if file is a zip file
     75                     self._RealGetContents()
     76                     # seek to start of directory and overwrite
     77                     self.fp.seek(self.start_dir, 0)
     78                 except BadZipfile:
     79                     # file is not a zip file, just append
     80                     self.fp.seek(0, 2)
     81 
     82                     # set the modified flag so central directory gets written
     83                     # even if no files are added to the archive
     84                     self._didModify = True
     85             else:
     86                 raise RuntimeError('Mode must be "r", "w" or "a"')
     87         except:
     88             fp = self.fp
     89             self.fp = None
     90             if not self._filePassed:
     91                 fp.close()
     92             raise
     93 
     94     def __enter__(self):
     95         return self
     96 
     97     def __exit__(self, type, value, traceback):
     98         self.close()
     99 
    100     def _RealGetContents(self):
    101         """Read in the table of contents for the ZIP file."""
    102         fp = self.fp
    103         try:
    104             endrec = _EndRecData(fp)
    105         except IOError:
    106             raise BadZipfile("File is not a zip file")
    107         if not endrec:
    108             raise BadZipfile, "File is not a zip file"
    109         if self.debug > 1:
    110             print endrec
    111         size_cd = endrec[_ECD_SIZE]             # bytes in central directory
    112         offset_cd = endrec[_ECD_OFFSET]         # offset of central directory
    113         self._comment = endrec[_ECD_COMMENT]    # archive comment
    114 
    115         # "concat" is zero, unless zip was concatenated to another file
    116         concat = endrec[_ECD_LOCATION] - size_cd - offset_cd
    117         if endrec[_ECD_SIGNATURE] == stringEndArchive64:
    118             # If Zip64 extension structures are present, account for them
    119             concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator)
    120 
    121         if self.debug > 2:
    122             inferred = concat + offset_cd
    123             print "given, inferred, offset", offset_cd, inferred, concat
    124         # self.start_dir:  Position of start of central directory
    125         self.start_dir = offset_cd + concat
    126         fp.seek(self.start_dir, 0)
    127         data = fp.read(size_cd)
    128         fp = cStringIO.StringIO(data)
    129         total = 0
    130         while total < size_cd:
    131             centdir = fp.read(sizeCentralDir)
    132             if len(centdir) != sizeCentralDir:
    133                 raise BadZipfile("Truncated central directory")
    134             centdir = struct.unpack(structCentralDir, centdir)
    135             if centdir[_CD_SIGNATURE] != stringCentralDir:
    136                 raise BadZipfile("Bad magic number for central directory")
    137             if self.debug > 2:
    138                 print centdir
    139             filename = fp.read(centdir[_CD_FILENAME_LENGTH])
    140             # Create ZipInfo instance to store file information
    141             x = ZipInfo(filename)
    142             x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH])
    143             x.comment = fp.read(centdir[_CD_COMMENT_LENGTH])
    144             x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET]
    145             (x.create_version, x.create_system, x.extract_version, x.reserved,
    146                 x.flag_bits, x.compress_type, t, d,
    147                 x.CRC, x.compress_size, x.file_size) = centdir[1:12]
    148             x.volume, x.internal_attr, x.external_attr = centdir[15:18]
    149             # Convert date/time code to (year, month, day, hour, min, sec)
    150             x._raw_time = t
    151             x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F,
    152                                      t>>11, (t>>5)&0x3F, (t&0x1F) * 2 )
    153 
    154             x._decodeExtra()
    155             x.header_offset = x.header_offset + concat
    156             x.filename = x._decodeFilename()
    157             self.filelist.append(x)
    158             self.NameToInfo[x.filename] = x
    159 
    160             # update total bytes read from central directory
    161             total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH]
    162                      + centdir[_CD_EXTRA_FIELD_LENGTH]
    163                      + centdir[_CD_COMMENT_LENGTH])
    164 
    165             if self.debug > 2:
    166                 print "total", total
    167 
    168 
    169     def namelist(self):
    170         """Return a list of file names in the archive."""
    171         l = []
    172         for data in self.filelist:
    173             l.append(data.filename)
    174         return l
    175 
    176     def infolist(self):
    177         """Return a list of class ZipInfo instances for files in the
    178         archive."""
    179         return self.filelist
    180 
    181     def printdir(self):
    182         """Print a table of contents for the zip file."""
    183         print "%-46s %19s %12s" % ("File Name", "Modified    ", "Size")
    184         for zinfo in self.filelist:
    185             date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6]
    186             print "%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size)
    187 
    188     def testzip(self):
    189         """Read all the files and check the CRC."""
    190         chunk_size = 2 ** 20
    191         for zinfo in self.filelist:
    192             try:
    193                 # Read by chunks, to avoid an OverflowError or a
    194                 # MemoryError with very large embedded files.
    195                 with self.open(zinfo.filename, "r") as f:
    196                     while f.read(chunk_size):     # Check CRC-32
    197                         pass
    198             except BadZipfile:
    199                 return zinfo.filename
    200 
    201     def getinfo(self, name):
    202         """Return the instance of ZipInfo given 'name'."""
    203         info = self.NameToInfo.get(name)
    204         if info is None:
    205             raise KeyError(
    206                 'There is no item named %r in the archive' % name)
    207 
    208         return info
    209 
    210     def setpassword(self, pwd):
    211         """Set default password for encrypted files."""
    212         self.pwd = pwd
    213 
    214     @property
    215     def comment(self):
    216         """The comment text associated with the ZIP file."""
    217         return self._comment
    218 
    219     @comment.setter
    220     def comment(self, comment):
    221         # check for valid comment length
    222         if len(comment) > ZIP_MAX_COMMENT:
    223             import warnings
    224             warnings.warn('Archive comment is too long; truncating to %d bytes'
    225                           % ZIP_MAX_COMMENT, stacklevel=2)
    226             comment = comment[:ZIP_MAX_COMMENT]
    227         self._comment = comment
    228         self._didModify = True
    229 
    230     def read(self, name, pwd=None):
    231         """Return file bytes (as a string) for name."""
    232         return self.open(name, "r", pwd).read()
    233 
    234     def open(self, name, mode="r", pwd=None):
    235         """Return file-like object for 'name'."""
    236         if mode not in ("r", "U", "rU"):
    237             raise RuntimeError, 'open() requires mode "r", "U", or "rU"'
    238         if not self.fp:
    239             raise RuntimeError, 
    240                   "Attempt to read ZIP archive that was already closed"
    241 
    242         # Only open a new file for instances where we were not
    243         # given a file object in the constructor
    244         if self._filePassed:
    245             zef_file = self.fp
    246             should_close = False
    247         else:
    248             zef_file = open(self.filename, 'rb')
    249             should_close = True
    250 
    251         try:
    252             # Make sure we have an info object
    253             if isinstance(name, ZipInfo):
    254                 # 'name' is already an info object
    255                 zinfo = name
    256             else:
    257                 # Get info object for name
    258                 zinfo = self.getinfo(name)
    259 
    260             zef_file.seek(zinfo.header_offset, 0)
    261 
    262             # Skip the file header:
    263             fheader = zef_file.read(sizeFileHeader)
    264             if len(fheader) != sizeFileHeader:
    265                 raise BadZipfile("Truncated file header")
    266             fheader = struct.unpack(structFileHeader, fheader)
    267             if fheader[_FH_SIGNATURE] != stringFileHeader:
    268                 raise BadZipfile("Bad magic number for file header")
    269 
    270             fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
    271             if fheader[_FH_EXTRA_FIELD_LENGTH]:
    272                 zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])
    273 
    274             if fname != zinfo.orig_filename:
    275                 raise BadZipfile, 
    276                         'File name in directory "%s" and header "%s" differ.' % (
    277                             zinfo.orig_filename, fname)
    278 
    279             # check for encrypted flag & handle password
    280             is_encrypted = zinfo.flag_bits & 0x1
    281             zd = None
    282             if is_encrypted:
    283                 if not pwd:
    284                     pwd = self.pwd
    285                 if not pwd:
    286                     raise RuntimeError, "File %s is encrypted, " 
    287                         "password required for extraction" % name
    288 
    289                 zd = _ZipDecrypter(pwd)
    290                 # The first 12 bytes in the cypher stream is an encryption header
    291                 #  used to strengthen the algorithm. The first 11 bytes are
    292                 #  completely random, while the 12th contains the MSB of the CRC,
    293                 #  or the MSB of the file time depending on the header type
    294                 #  and is used to check the correctness of the password.
    295                 bytes = zef_file.read(12)
    296                 h = map(zd, bytes[0:12])
    297                 if zinfo.flag_bits & 0x8:
    298                     # compare against the file type from extended local headers
    299                     check_byte = (zinfo._raw_time >> 8) & 0xff
    300                 else:
    301                     # compare against the CRC otherwise
    302                     check_byte = (zinfo.CRC >> 24) & 0xff
    303                 if ord(h[11]) != check_byte:
    304                     raise RuntimeError("Bad password for file", name)
    305 
    306             return ZipExtFile(zef_file, mode, zinfo, zd,
    307                     close_fileobj=should_close)
    308         except:
    309             if should_close:
    310                 zef_file.close()
    311             raise
    312 
    313     def extract(self, member, path=None, pwd=None):
    314         """Extract a member from the archive to the current working directory,
    315            using its full name. Its file information is extracted as accurately
    316            as possible. `member' may be a filename or a ZipInfo object. You can
    317            specify a different directory using `path'.
    318         """
    319         if not isinstance(member, ZipInfo):
    320             member = self.getinfo(member)
    321 
    322         if path is None:
    323             path = os.getcwd()
    324 
    325         return self._extract_member(member, path, pwd)
    326 
    327     def extractall(self, path=None, members=None, pwd=None):
    328         """Extract all members from the archive to the current working
    329            directory. `path' specifies a different directory to extract to.
    330            `members' is optional and must be a subset of the list returned
    331            by namelist().
    332         """
    333         if members is None:
    334             members = self.namelist()
    335 
    336         for zipinfo in members:
    337             self.extract(zipinfo, path, pwd)
    338 
    339     def _extract_member(self, member, targetpath, pwd):
    340         """Extract the ZipInfo object 'member' to a physical
    341            file on the path targetpath.
    342         """
    343         # build the destination pathname, replacing
    344         # forward slashes to platform specific separators.
    345         arcname = member.filename.replace('/', os.path.sep)
    346 
    347         if os.path.altsep:
    348             arcname = arcname.replace(os.path.altsep, os.path.sep)
    349         # interpret absolute pathname as relative, remove drive letter or
    350         # UNC path, redundant separators, "." and ".." components.
    351         arcname = os.path.splitdrive(arcname)[1]
    352         arcname = os.path.sep.join(x for x in arcname.split(os.path.sep)
    353                     if x not in ('', os.path.curdir, os.path.pardir))
    354         if os.path.sep == '\':
    355             # filter illegal characters on Windows
    356             illegal = ':<>|"?*'
    357             if isinstance(arcname, unicode):
    358                 table = {ord(c): ord('_') for c in illegal}
    359             else:
    360                 table = string.maketrans(illegal, '_' * len(illegal))
    361             arcname = arcname.translate(table)
    362             # remove trailing dots
    363             arcname = (x.rstrip('.') for x in arcname.split(os.path.sep))
    364             arcname = os.path.sep.join(x for x in arcname if x)
    365 
    366         targetpath = os.path.join(targetpath, arcname)
    367         targetpath = os.path.normpath(targetpath)
    368 
    369         # Create all upper directories if necessary.
    370         upperdirs = os.path.dirname(targetpath)
    371         if upperdirs and not os.path.exists(upperdirs):
    372             os.makedirs(upperdirs)
    373 
    374         if member.filename[-1] == '/':
    375             if not os.path.isdir(targetpath):
    376                 os.mkdir(targetpath)
    377             return targetpath
    378 
    379         with self.open(member, pwd=pwd) as source, 
    380              file(targetpath, "wb") as target:
    381             shutil.copyfileobj(source, target)
    382 
    383         return targetpath
    384 
    385     def _writecheck(self, zinfo):
    386         """Check for errors before writing a file to the archive."""
    387         if zinfo.filename in self.NameToInfo:
    388             import warnings
    389             warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3)
    390         if self.mode not in ("w", "a"):
    391             raise RuntimeError, 'write() requires mode "w" or "a"'
    392         if not self.fp:
    393             raise RuntimeError, 
    394                   "Attempt to write ZIP archive that was already closed"
    395         if zinfo.compress_type == ZIP_DEFLATED and not zlib:
    396             raise RuntimeError, 
    397                   "Compression requires the (missing) zlib module"
    398         if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED):
    399             raise RuntimeError, 
    400                   "That compression method is not supported"
    401         if not self._allowZip64:
    402             requires_zip64 = None
    403             if len(self.filelist) >= ZIP_FILECOUNT_LIMIT:
    404                 requires_zip64 = "Files count"
    405             elif zinfo.file_size > ZIP64_LIMIT:
    406                 requires_zip64 = "Filesize"
    407             elif zinfo.header_offset > ZIP64_LIMIT:
    408                 requires_zip64 = "Zipfile size"
    409             if requires_zip64:
    410                 raise LargeZipFile(requires_zip64 +
    411                                    " would require ZIP64 extensions")
    412 
    413     def write(self, filename, arcname=None, compress_type=None):
    414         """Put the bytes from filename into the archive under the name
    415         arcname."""
    416         if not self.fp:
    417             raise RuntimeError(
    418                   "Attempt to write to ZIP archive that was already closed")
    419 
    420         st = os.stat(filename)
    421         isdir = stat.S_ISDIR(st.st_mode)
    422         mtime = time.localtime(st.st_mtime)
    423         date_time = mtime[0:6]
    424         # Create ZipInfo instance to store file information
    425         if arcname is None:
    426             arcname = filename
    427         arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
    428         while arcname[0] in (os.sep, os.altsep):
    429             arcname = arcname[1:]
    430         if isdir:
    431             arcname += '/'
    432         zinfo = ZipInfo(arcname, date_time)
    433         zinfo.external_attr = (st[0] & 0xFFFF) << 16L      # Unix attributes
    434         if compress_type is None:
    435             zinfo.compress_type = self.compression
    436         else:
    437             zinfo.compress_type = compress_type
    438 
    439         zinfo.file_size = st.st_size
    440         zinfo.flag_bits = 0x00
    441         zinfo.header_offset = self.fp.tell()    # Start of header bytes
    442 
    443         self._writecheck(zinfo)
    444         self._didModify = True
    445 
    446         if isdir:
    447             zinfo.file_size = 0
    448             zinfo.compress_size = 0
    449             zinfo.CRC = 0
    450             zinfo.external_attr |= 0x10  # MS-DOS directory flag
    451             self.filelist.append(zinfo)
    452             self.NameToInfo[zinfo.filename] = zinfo
    453             self.fp.write(zinfo.FileHeader(False))
    454             return
    455 
    456         with open(filename, "rb") as fp:
    457             # Must overwrite CRC and sizes with correct data later
    458             zinfo.CRC = CRC = 0
    459             zinfo.compress_size = compress_size = 0
    460             # Compressed size can be larger than uncompressed size
    461             zip64 = self._allowZip64 and 
    462                     zinfo.file_size * 1.05 > ZIP64_LIMIT
    463             self.fp.write(zinfo.FileHeader(zip64))
    464             if zinfo.compress_type == ZIP_DEFLATED:
    465                 cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
    466                      zlib.DEFLATED, -15)
    467             else:
    468                 cmpr = None
    469             file_size = 0
    470             while 1:
    471                 buf = fp.read(1024 * 8)
    472                 if not buf:
    473                     break
    474                 file_size = file_size + len(buf)
    475                 CRC = crc32(buf, CRC) & 0xffffffff
    476                 if cmpr:
    477                     buf = cmpr.compress(buf)
    478                     compress_size = compress_size + len(buf)
    479                 self.fp.write(buf)
    480         if cmpr:
    481             buf = cmpr.flush()
    482             compress_size = compress_size + len(buf)
    483             self.fp.write(buf)
    484             zinfo.compress_size = compress_size
    485         else:
    486             zinfo.compress_size = file_size
    487         zinfo.CRC = CRC
    488         zinfo.file_size = file_size
    489         if not zip64 and self._allowZip64:
    490             if file_size > ZIP64_LIMIT:
    491                 raise RuntimeError('File size has increased during compressing')
    492             if compress_size > ZIP64_LIMIT:
    493                 raise RuntimeError('Compressed size larger than uncompressed size')
    494         # Seek backwards and write file header (which will now include
    495         # correct CRC and file sizes)
    496         position = self.fp.tell()       # Preserve current position in file
    497         self.fp.seek(zinfo.header_offset, 0)
    498         self.fp.write(zinfo.FileHeader(zip64))
    499         self.fp.seek(position, 0)
    500         self.filelist.append(zinfo)
    501         self.NameToInfo[zinfo.filename] = zinfo
    502 
    503     def writestr(self, zinfo_or_arcname, bytes, compress_type=None):
    504         """Write a file into the archive.  The contents is the string
    505         'bytes'.  'zinfo_or_arcname' is either a ZipInfo instance or
    506         the name of the file in the archive."""
    507         if not isinstance(zinfo_or_arcname, ZipInfo):
    508             zinfo = ZipInfo(filename=zinfo_or_arcname,
    509                             date_time=time.localtime(time.time())[:6])
    510 
    511             zinfo.compress_type = self.compression
    512             if zinfo.filename[-1] == '/':
    513                 zinfo.external_attr = 0o40775 << 16   # drwxrwxr-x
    514                 zinfo.external_attr |= 0x10           # MS-DOS directory flag
    515             else:
    516                 zinfo.external_attr = 0o600 << 16     # ?rw-------
    517         else:
    518             zinfo = zinfo_or_arcname
    519 
    520         if not self.fp:
    521             raise RuntimeError(
    522                   "Attempt to write to ZIP archive that was already closed")
    523 
    524         if compress_type is not None:
    525             zinfo.compress_type = compress_type
    526 
    527         zinfo.file_size = len(bytes)            # Uncompressed size
    528         zinfo.header_offset = self.fp.tell()    # Start of header bytes
    529         self._writecheck(zinfo)
    530         self._didModify = True
    531         zinfo.CRC = crc32(bytes) & 0xffffffff       # CRC-32 checksum
    532         if zinfo.compress_type == ZIP_DEFLATED:
    533             co = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
    534                  zlib.DEFLATED, -15)
    535             bytes = co.compress(bytes) + co.flush()
    536             zinfo.compress_size = len(bytes)    # Compressed size
    537         else:
    538             zinfo.compress_size = zinfo.file_size
    539         zip64 = zinfo.file_size > ZIP64_LIMIT or 
    540                 zinfo.compress_size > ZIP64_LIMIT
    541         if zip64 and not self._allowZip64:
    542             raise LargeZipFile("Filesize would require ZIP64 extensions")
    543         self.fp.write(zinfo.FileHeader(zip64))
    544         self.fp.write(bytes)
    545         if zinfo.flag_bits & 0x08:
    546             # Write CRC and file sizes after the file data
    547             fmt = '<LQQ' if zip64 else '<LLL'
    548             self.fp.write(struct.pack(fmt, zinfo.CRC, zinfo.compress_size,
    549                   zinfo.file_size))
    550         self.fp.flush()
    551         self.filelist.append(zinfo)
    552         self.NameToInfo[zinfo.filename] = zinfo
    553 
    554     def __del__(self):
    555         """Call the "close()" method in case the user forgot."""
    556         self.close()
    557 
    558     def close(self):
    559         """Close the file, and for mode "w" and "a" write the ending
    560         records."""
    561         if self.fp is None:
    562             return
    563 
    564         try:
    565             if self.mode in ("w", "a") and self._didModify: # write ending records
    566                 pos1 = self.fp.tell()
    567                 for zinfo in self.filelist:         # write central directory
    568                     dt = zinfo.date_time
    569                     dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
    570                     dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)
    571                     extra = []
    572                     if zinfo.file_size > ZIP64_LIMIT 
    573                             or zinfo.compress_size > ZIP64_LIMIT:
    574                         extra.append(zinfo.file_size)
    575                         extra.append(zinfo.compress_size)
    576                         file_size = 0xffffffff
    577                         compress_size = 0xffffffff
    578                     else:
    579                         file_size = zinfo.file_size
    580                         compress_size = zinfo.compress_size
    581 
    582                     if zinfo.header_offset > ZIP64_LIMIT:
    583                         extra.append(zinfo.header_offset)
    584                         header_offset = 0xffffffffL
    585                     else:
    586                         header_offset = zinfo.header_offset
    587 
    588                     extra_data = zinfo.extra
    589                     if extra:
    590                         # Append a ZIP64 field to the extra's
    591                         extra_data = struct.pack(
    592                                 '<HH' + 'Q'*len(extra),
    593                                 1, 8*len(extra), *extra) + extra_data
    594 
    595                         extract_version = max(45, zinfo.extract_version)
    596                         create_version = max(45, zinfo.create_version)
    597                     else:
    598                         extract_version = zinfo.extract_version
    599                         create_version = zinfo.create_version
    600 
    601                     try:
    602                         filename, flag_bits = zinfo._encodeFilenameFlags()
    603                         centdir = struct.pack(structCentralDir,
    604                         stringCentralDir, create_version,
    605                         zinfo.create_system, extract_version, zinfo.reserved,
    606                         flag_bits, zinfo.compress_type, dostime, dosdate,
    607                         zinfo.CRC, compress_size, file_size,
    608                         len(filename), len(extra_data), len(zinfo.comment),
    609                         0, zinfo.internal_attr, zinfo.external_attr,
    610                         header_offset)
    611                     except DeprecationWarning:
    612                         print >>sys.stderr, (structCentralDir,
    613                         stringCentralDir, create_version,
    614                         zinfo.create_system, extract_version, zinfo.reserved,
    615                         zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
    616                         zinfo.CRC, compress_size, file_size,
    617                         len(zinfo.filename), len(extra_data), len(zinfo.comment),
    618                         0, zinfo.internal_attr, zinfo.external_attr,
    619                         header_offset)
    620                         raise
    621                     self.fp.write(centdir)
    622                     self.fp.write(filename)
    623                     self.fp.write(extra_data)
    624                     self.fp.write(zinfo.comment)
    625 
    626                 pos2 = self.fp.tell()
    627                 # Write end-of-zip-archive record
    628                 centDirCount = len(self.filelist)
    629                 centDirSize = pos2 - pos1
    630                 centDirOffset = pos1
    631                 requires_zip64 = None
    632                 if centDirCount > ZIP_FILECOUNT_LIMIT:
    633                     requires_zip64 = "Files count"
    634                 elif centDirOffset > ZIP64_LIMIT:
    635                     requires_zip64 = "Central directory offset"
    636                 elif centDirSize > ZIP64_LIMIT:
    637                     requires_zip64 = "Central directory size"
    638                 if requires_zip64:
    639                     # Need to write the ZIP64 end-of-archive records
    640                     if not self._allowZip64:
    641                         raise LargeZipFile(requires_zip64 +
    642                                            " would require ZIP64 extensions")
    643                     zip64endrec = struct.pack(
    644                             structEndArchive64, stringEndArchive64,
    645                             44, 45, 45, 0, 0, centDirCount, centDirCount,
    646                             centDirSize, centDirOffset)
    647                     self.fp.write(zip64endrec)
    648 
    649                     zip64locrec = struct.pack(
    650                             structEndArchive64Locator,
    651                             stringEndArchive64Locator, 0, pos2, 1)
    652                     self.fp.write(zip64locrec)
    653                     centDirCount = min(centDirCount, 0xFFFF)
    654                     centDirSize = min(centDirSize, 0xFFFFFFFF)
    655                     centDirOffset = min(centDirOffset, 0xFFFFFFFF)
    656 
    657                 endrec = struct.pack(structEndArchive, stringEndArchive,
    658                                     0, 0, centDirCount, centDirCount,
    659                                     centDirSize, centDirOffset, len(self._comment))
    660                 self.fp.write(endrec)
    661                 self.fp.write(self._comment)
    662                 self.fp.flush()
    663         finally:
    664             fp = self.fp
    665             self.fp = None
    666             if not self._filePassed:
    667                 fp.close()
    zipfile的源代码
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import zipfile
     7 z = zipfile.ZipFile("ziptest.zip","w")  #创建一个叫”ziptest.zip“的压缩文件
     8 z.write(r"D:pythondaimaDAY5README",arcname="README") #将该文件放入到”ziptest.zip“的压缩文件中,后面的arcname参数的意思是指压缩这个文件的即可,不用压缩这个文件的所在的绝对路径。如果不加这个参数的话,会把该文件的当前位置的绝对路径都一起压缩了
     9 z.write(r"D:pythondaimaDAY3modify.txt",arcname="modify.txt") #同上
    10 z.write("day5.zip") #将当前路径的文件压缩到”ziptest.zip“的压缩文件中
    11 z.close()  #关闭压缩文件,这个时候就可以将文件存入进去了。
    zipfile压缩的用法
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import zipfile
     7 z = zipfile.ZipFile("ziptest.zip","r")
     8 z.extract("README") #进行解压一个叫“README”的文件
     9 z.extractall(path=r"D:pythondaimaDAY5	est_1") #将z这个压缩包的内容全部解压出来,path表示执行解压后的存放路径
    10 z.extractall(members=["modify.txt"])  #表示将z这个压缩包全部解压出来,出了列表中的文件,注意不支持模糊匹配哟!
    11 z.close()
    zipfile解压的用法

    12>.tarfile用法扩充

      1 #!/usr/bin/env python
      2 #_*_coding:utf-8_*_
      3 #@author :yinzhengjie
      4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
      5 #EMAIL:y1053419035@qq.com
      6 class TarFile(object):
      7     """The TarFile Class provides an interface to tar archives.
      8     """
      9 
     10     debug = 0                   # May be set from 0 (no msgs) to 3 (all msgs)
     11 
     12     dereference = False         # If true, add content of linked file to the
     13                                 # tar file, else the link.
     14 
     15     ignore_zeros = False        # If true, skips empty or invalid blocks and
     16                                 # continues processing.
     17 
     18     errorlevel = 1              # If 0, fatal errors only appear in debug
     19                                 # messages (if debug >= 0). If > 0, errors
     20                                 # are passed to the caller as exceptions.
     21 
     22     format = DEFAULT_FORMAT     # The format to use when creating an archive.
     23 
     24     encoding = ENCODING         # Encoding for 8-bit character strings.
     25 
     26     errors = None               # Error handler for unicode conversion.
     27 
     28     tarinfo = TarInfo           # The default TarInfo class to use.
     29 
     30     fileobject = ExFileObject   # The default ExFileObject class to use.
     31 
     32     def __init__(self, name=None, mode="r", fileobj=None, format=None,
     33             tarinfo=None, dereference=None, ignore_zeros=None, encoding=None,
     34             errors=None, pax_headers=None, debug=None, errorlevel=None):
     35         """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
     36            read from an existing archive, 'a' to append data to an existing
     37            file or 'w' to create a new file overwriting an existing one. `mode'
     38            defaults to 'r'.
     39            If `fileobj' is given, it is used for reading or writing data. If it
     40            can be determined, `mode' is overridden by `fileobj's mode.
     41            `fileobj' is not closed, when TarFile is closed.
     42         """
     43         modes = {"r": "rb", "a": "r+b", "w": "wb"}
     44         if mode not in modes:
     45             raise ValueError("mode must be 'r', 'a' or 'w'")
     46         self.mode = mode
     47         self._mode = modes[mode]
     48 
     49         if not fileobj:
     50             if self.mode == "a" and not os.path.exists(name):
     51                 # Create nonexistent files in append mode.
     52                 self.mode = "w"
     53                 self._mode = "wb"
     54             fileobj = bltn_open(name, self._mode)
     55             self._extfileobj = False
     56         else:
     57             if name is None and hasattr(fileobj, "name"):
     58                 name = fileobj.name
     59             if hasattr(fileobj, "mode"):
     60                 self._mode = fileobj.mode
     61             self._extfileobj = True
     62         self.name = os.path.abspath(name) if name else None
     63         self.fileobj = fileobj
     64 
     65         # Init attributes.
     66         if format is not None:
     67             self.format = format
     68         if tarinfo is not None:
     69             self.tarinfo = tarinfo
     70         if dereference is not None:
     71             self.dereference = dereference
     72         if ignore_zeros is not None:
     73             self.ignore_zeros = ignore_zeros
     74         if encoding is not None:
     75             self.encoding = encoding
     76 
     77         if errors is not None:
     78             self.errors = errors
     79         elif mode == "r":
     80             self.errors = "utf-8"
     81         else:
     82             self.errors = "strict"
     83 
     84         if pax_headers is not None and self.format == PAX_FORMAT:
     85             self.pax_headers = pax_headers
     86         else:
     87             self.pax_headers = {}
     88 
     89         if debug is not None:
     90             self.debug = debug
     91         if errorlevel is not None:
     92             self.errorlevel = errorlevel
     93 
     94         # Init datastructures.
     95         self.closed = False
     96         self.members = []       # list of members as TarInfo objects
     97         self._loaded = False    # flag if all members have been read
     98         self.offset = self.fileobj.tell()
     99                                 # current position in the archive file
    100         self.inodes = {}        # dictionary caching the inodes of
    101                                 # archive members already added
    102 
    103         try:
    104             if self.mode == "r":
    105                 self.firstmember = None
    106                 self.firstmember = self.next()
    107 
    108             if self.mode == "a":
    109                 # Move to the end of the archive,
    110                 # before the first empty block.
    111                 while True:
    112                     self.fileobj.seek(self.offset)
    113                     try:
    114                         tarinfo = self.tarinfo.fromtarfile(self)
    115                         self.members.append(tarinfo)
    116                     except EOFHeaderError:
    117                         self.fileobj.seek(self.offset)
    118                         break
    119                     except HeaderError, e:
    120                         raise ReadError(str(e))
    121 
    122             if self.mode in "aw":
    123                 self._loaded = True
    124 
    125                 if self.pax_headers:
    126                     buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy())
    127                     self.fileobj.write(buf)
    128                     self.offset += len(buf)
    129         except:
    130             if not self._extfileobj:
    131                 self.fileobj.close()
    132             self.closed = True
    133             raise
    134 
    135     def _getposix(self):
    136         return self.format == USTAR_FORMAT
    137     def _setposix(self, value):
    138         import warnings
    139         warnings.warn("use the format attribute instead", DeprecationWarning,
    140                       2)
    141         if value:
    142             self.format = USTAR_FORMAT
    143         else:
    144             self.format = GNU_FORMAT
    145     posix = property(_getposix, _setposix)
    146 
    147     #--------------------------------------------------------------------------
    148     # Below are the classmethods which act as alternate constructors to the
    149     # TarFile class. The open() method is the only one that is needed for
    150     # public use; it is the "super"-constructor and is able to select an
    151     # adequate "sub"-constructor for a particular compression using the mapping
    152     # from OPEN_METH.
    153     #
    154     # This concept allows one to subclass TarFile without losing the comfort of
    155     # the super-constructor. A sub-constructor is registered and made available
    156     # by adding it to the mapping in OPEN_METH.
    157 
    158     @classmethod
    159     def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs):
    160         """Open a tar archive for reading, writing or appending. Return
    161            an appropriate TarFile class.
    162 
    163            mode:
    164            'r' or 'r:*' open for reading with transparent compression
    165            'r:'         open for reading exclusively uncompressed
    166            'r:gz'       open for reading with gzip compression
    167            'r:bz2'      open for reading with bzip2 compression
    168            'a' or 'a:'  open for appending, creating the file if necessary
    169            'w' or 'w:'  open for writing without compression
    170            'w:gz'       open for writing with gzip compression
    171            'w:bz2'      open for writing with bzip2 compression
    172 
    173            'r|*'        open a stream of tar blocks with transparent compression
    174            'r|'         open an uncompressed stream of tar blocks for reading
    175            'r|gz'       open a gzip compressed stream of tar blocks
    176            'r|bz2'      open a bzip2 compressed stream of tar blocks
    177            'w|'         open an uncompressed stream for writing
    178            'w|gz'       open a gzip compressed stream for writing
    179            'w|bz2'      open a bzip2 compressed stream for writing
    180         """
    181 
    182         if not name and not fileobj:
    183             raise ValueError("nothing to open")
    184 
    185         if mode in ("r", "r:*"):
    186             # Find out which *open() is appropriate for opening the file.
    187             for comptype in cls.OPEN_METH:
    188                 func = getattr(cls, cls.OPEN_METH[comptype])
    189                 if fileobj is not None:
    190                     saved_pos = fileobj.tell()
    191                 try:
    192                     return func(name, "r", fileobj, **kwargs)
    193                 except (ReadError, CompressionError), e:
    194                     if fileobj is not None:
    195                         fileobj.seek(saved_pos)
    196                     continue
    197             raise ReadError("file could not be opened successfully")
    198 
    199         elif ":" in mode:
    200             filemode, comptype = mode.split(":", 1)
    201             filemode = filemode or "r"
    202             comptype = comptype or "tar"
    203 
    204             # Select the *open() function according to
    205             # given compression.
    206             if comptype in cls.OPEN_METH:
    207                 func = getattr(cls, cls.OPEN_METH[comptype])
    208             else:
    209                 raise CompressionError("unknown compression type %r" % comptype)
    210             return func(name, filemode, fileobj, **kwargs)
    211 
    212         elif "|" in mode:
    213             filemode, comptype = mode.split("|", 1)
    214             filemode = filemode or "r"
    215             comptype = comptype or "tar"
    216 
    217             if filemode not in ("r", "w"):
    218                 raise ValueError("mode must be 'r' or 'w'")
    219 
    220             stream = _Stream(name, filemode, comptype, fileobj, bufsize)
    221             try:
    222                 t = cls(name, filemode, stream, **kwargs)
    223             except:
    224                 stream.close()
    225                 raise
    226             t._extfileobj = False
    227             return t
    228 
    229         elif mode in ("a", "w"):
    230             return cls.taropen(name, mode, fileobj, **kwargs)
    231 
    232         raise ValueError("undiscernible mode")
    233 
    234     @classmethod
    235     def taropen(cls, name, mode="r", fileobj=None, **kwargs):
    236         """Open uncompressed tar archive name for reading or writing.
    237         """
    238         if mode not in ("r", "a", "w"):
    239             raise ValueError("mode must be 'r', 'a' or 'w'")
    240         return cls(name, mode, fileobj, **kwargs)
    241 
    242     @classmethod
    243     def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
    244         """Open gzip compressed tar archive name for reading or writing.
    245            Appending is not allowed.
    246         """
    247         if mode not in ("r", "w"):
    248             raise ValueError("mode must be 'r' or 'w'")
    249 
    250         try:
    251             import gzip
    252             gzip.GzipFile
    253         except (ImportError, AttributeError):
    254             raise CompressionError("gzip module is not available")
    255 
    256         try:
    257             fileobj = gzip.GzipFile(name, mode, compresslevel, fileobj)
    258         except OSError:
    259             if fileobj is not None and mode == 'r':
    260                 raise ReadError("not a gzip file")
    261             raise
    262 
    263         try:
    264             t = cls.taropen(name, mode, fileobj, **kwargs)
    265         except IOError:
    266             fileobj.close()
    267             if mode == 'r':
    268                 raise ReadError("not a gzip file")
    269             raise
    270         except:
    271             fileobj.close()
    272             raise
    273         t._extfileobj = False
    274         return t
    275 
    276     @classmethod
    277     def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs):
    278         """Open bzip2 compressed tar archive name for reading or writing.
    279            Appending is not allowed.
    280         """
    281         if mode not in ("r", "w"):
    282             raise ValueError("mode must be 'r' or 'w'.")
    283 
    284         try:
    285             import bz2
    286         except ImportError:
    287             raise CompressionError("bz2 module is not available")
    288 
    289         if fileobj is not None:
    290             fileobj = _BZ2Proxy(fileobj, mode)
    291         else:
    292             fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel)
    293 
    294         try:
    295             t = cls.taropen(name, mode, fileobj, **kwargs)
    296         except (IOError, EOFError):
    297             fileobj.close()
    298             if mode == 'r':
    299                 raise ReadError("not a bzip2 file")
    300             raise
    301         except:
    302             fileobj.close()
    303             raise
    304         t._extfileobj = False
    305         return t
    306 
    307     # All *open() methods are registered here.
    308     OPEN_METH = {
    309         "tar": "taropen",   # uncompressed tar
    310         "gz":  "gzopen",    # gzip compressed tar
    311         "bz2": "bz2open"    # bzip2 compressed tar
    312     }
    313 
    314     #--------------------------------------------------------------------------
    315     # The public methods which TarFile provides:
    316 
    317     def close(self):
    318         """Close the TarFile. In write-mode, two finishing zero blocks are
    319            appended to the archive.
    320         """
    321         if self.closed:
    322             return
    323 
    324         if self.mode in "aw":
    325             self.fileobj.write(NUL * (BLOCKSIZE * 2))
    326             self.offset += (BLOCKSIZE * 2)
    327             # fill up the end with zero-blocks
    328             # (like option -b20 for tar does)
    329             blocks, remainder = divmod(self.offset, RECORDSIZE)
    330             if remainder > 0:
    331                 self.fileobj.write(NUL * (RECORDSIZE - remainder))
    332 
    333         if not self._extfileobj:
    334             self.fileobj.close()
    335         self.closed = True
    336 
    337     def getmember(self, name):
    338         """Return a TarInfo object for member `name'. If `name' can not be
    339            found in the archive, KeyError is raised. If a member occurs more
    340            than once in the archive, its last occurrence is assumed to be the
    341            most up-to-date version.
    342         """
    343         tarinfo = self._getmember(name)
    344         if tarinfo is None:
    345             raise KeyError("filename %r not found" % name)
    346         return tarinfo
    347 
    348     def getmembers(self):
    349         """Return the members of the archive as a list of TarInfo objects. The
    350            list has the same order as the members in the archive.
    351         """
    352         self._check()
    353         if not self._loaded:    # if we want to obtain a list of
    354             self._load()        # all members, we first have to
    355                                 # scan the whole archive.
    356         return self.members
    357 
    358     def getnames(self):
    359         """Return the members of the archive as a list of their names. It has
    360            the same order as the list returned by getmembers().
    361         """
    362         return [tarinfo.name for tarinfo in self.getmembers()]
    363 
    364     def gettarinfo(self, name=None, arcname=None, fileobj=None):
    365         """Create a TarInfo object for either the file `name' or the file
    366            object `fileobj' (using os.fstat on its file descriptor). You can
    367            modify some of the TarInfo's attributes before you add it using
    368            addfile(). If given, `arcname' specifies an alternative name for the
    369            file in the archive.
    370         """
    371         self._check("aw")
    372 
    373         # When fileobj is given, replace name by
    374         # fileobj's real name.
    375         if fileobj is not None:
    376             name = fileobj.name
    377 
    378         # Building the name of the member in the archive.
    379         # Backward slashes are converted to forward slashes,
    380         # Absolute paths are turned to relative paths.
    381         if arcname is None:
    382             arcname = name
    383         drv, arcname = os.path.splitdrive(arcname)
    384         arcname = arcname.replace(os.sep, "/")
    385         arcname = arcname.lstrip("/")
    386 
    387         # Now, fill the TarInfo object with
    388         # information specific for the file.
    389         tarinfo = self.tarinfo()
    390         tarinfo.tarfile = self
    391 
    392         # Use os.stat or os.lstat, depending on platform
    393         # and if symlinks shall be resolved.
    394         if fileobj is None:
    395             if hasattr(os, "lstat") and not self.dereference:
    396                 statres = os.lstat(name)
    397             else:
    398                 statres = os.stat(name)
    399         else:
    400             statres = os.fstat(fileobj.fileno())
    401         linkname = ""
    402 
    403         stmd = statres.st_mode
    404         if stat.S_ISREG(stmd):
    405             inode = (statres.st_ino, statres.st_dev)
    406             if not self.dereference and statres.st_nlink > 1 and 
    407                     inode in self.inodes and arcname != self.inodes[inode]:
    408                 # Is it a hardlink to an already
    409                 # archived file?
    410                 type = LNKTYPE
    411                 linkname = self.inodes[inode]
    412             else:
    413                 # The inode is added only if its valid.
    414                 # For win32 it is always 0.
    415                 type = REGTYPE
    416                 if inode[0]:
    417                     self.inodes[inode] = arcname
    418         elif stat.S_ISDIR(stmd):
    419             type = DIRTYPE
    420         elif stat.S_ISFIFO(stmd):
    421             type = FIFOTYPE
    422         elif stat.S_ISLNK(stmd):
    423             type = SYMTYPE
    424             linkname = os.readlink(name)
    425         elif stat.S_ISCHR(stmd):
    426             type = CHRTYPE
    427         elif stat.S_ISBLK(stmd):
    428             type = BLKTYPE
    429         else:
    430             return None
    431 
    432         # Fill the TarInfo object with all
    433         # information we can get.
    434         tarinfo.name = arcname
    435         tarinfo.mode = stmd
    436         tarinfo.uid = statres.st_uid
    437         tarinfo.gid = statres.st_gid
    438         if type == REGTYPE:
    439             tarinfo.size = statres.st_size
    440         else:
    441             tarinfo.size = 0L
    442         tarinfo.mtime = statres.st_mtime
    443         tarinfo.type = type
    444         tarinfo.linkname = linkname
    445         if pwd:
    446             try:
    447                 tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0]
    448             except KeyError:
    449                 pass
    450         if grp:
    451             try:
    452                 tarinfo.gname = grp.getgrgid(tarinfo.gid)[0]
    453             except KeyError:
    454                 pass
    455 
    456         if type in (CHRTYPE, BLKTYPE):
    457             if hasattr(os, "major") and hasattr(os, "minor"):
    458                 tarinfo.devmajor = os.major(statres.st_rdev)
    459                 tarinfo.devminor = os.minor(statres.st_rdev)
    460         return tarinfo
    461 
    462     def list(self, verbose=True):
    463         """Print a table of contents to sys.stdout. If `verbose' is False, only
    464            the names of the members are printed. If it is True, an `ls -l'-like
    465            output is produced.
    466         """
    467         self._check()
    468 
    469         for tarinfo in self:
    470             if verbose:
    471                 print filemode(tarinfo.mode),
    472                 print "%s/%s" % (tarinfo.uname or tarinfo.uid,
    473                                  tarinfo.gname or tarinfo.gid),
    474                 if tarinfo.ischr() or tarinfo.isblk():
    475                     print "%10s" % ("%d,%d" 
    476                                     % (tarinfo.devmajor, tarinfo.devminor)),
    477                 else:
    478                     print "%10d" % tarinfo.size,
    479                 print "%d-%02d-%02d %02d:%02d:%02d" 
    480                       % time.localtime(tarinfo.mtime)[:6],
    481 
    482             print tarinfo.name + ("/" if tarinfo.isdir() else ""),
    483 
    484             if verbose:
    485                 if tarinfo.issym():
    486                     print "->", tarinfo.linkname,
    487                 if tarinfo.islnk():
    488                     print "link to", tarinfo.linkname,
    489             print
    490 
    491     def add(self, name, arcname=None, recursive=True, exclude=None, filter=None):
    492         """Add the file `name' to the archive. `name' may be any type of file
    493            (directory, fifo, symbolic link, etc.). If given, `arcname'
    494            specifies an alternative name for the file in the archive.
    495            Directories are added recursively by default. This can be avoided by
    496            setting `recursive' to False. `exclude' is a function that should
    497            return True for each filename to be excluded. `filter' is a function
    498            that expects a TarInfo object argument and returns the changed
    499            TarInfo object, if it returns None the TarInfo object will be
    500            excluded from the archive.
    501         """
    502         self._check("aw")
    503 
    504         if arcname is None:
    505             arcname = name
    506 
    507         # Exclude pathnames.
    508         if exclude is not None:
    509             import warnings
    510             warnings.warn("use the filter argument instead",
    511                     DeprecationWarning, 2)
    512             if exclude(name):
    513                 self._dbg(2, "tarfile: Excluded %r" % name)
    514                 return
    515 
    516         # Skip if somebody tries to archive the archive...
    517         if self.name is not None and os.path.abspath(name) == self.name:
    518             self._dbg(2, "tarfile: Skipped %r" % name)
    519             return
    520 
    521         self._dbg(1, name)
    522 
    523         # Create a TarInfo object from the file.
    524         tarinfo = self.gettarinfo(name, arcname)
    525 
    526         if tarinfo is None:
    527             self._dbg(1, "tarfile: Unsupported type %r" % name)
    528             return
    529 
    530         # Change or exclude the TarInfo object.
    531         if filter is not None:
    532             tarinfo = filter(tarinfo)
    533             if tarinfo is None:
    534                 self._dbg(2, "tarfile: Excluded %r" % name)
    535                 return
    536 
    537         # Append the tar header and data to the archive.
    538         if tarinfo.isreg():
    539             with bltn_open(name, "rb") as f:
    540                 self.addfile(tarinfo, f)
    541 
    542         elif tarinfo.isdir():
    543             self.addfile(tarinfo)
    544             if recursive:
    545                 for f in os.listdir(name):
    546                     self.add(os.path.join(name, f), os.path.join(arcname, f),
    547                             recursive, exclude, filter)
    548 
    549         else:
    550             self.addfile(tarinfo)
    551 
    552     def addfile(self, tarinfo, fileobj=None):
    553         """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
    554            given, tarinfo.size bytes are read from it and added to the archive.
    555            You can create TarInfo objects using gettarinfo().
    556            On Windows platforms, `fileobj' should always be opened with mode
    557            'rb' to avoid irritation about the file size.
    558         """
    559         self._check("aw")
    560 
    561         tarinfo = copy.copy(tarinfo)
    562 
    563         buf = tarinfo.tobuf(self.format, self.encoding, self.errors)
    564         self.fileobj.write(buf)
    565         self.offset += len(buf)
    566 
    567         # If there's data to follow, append it.
    568         if fileobj is not None:
    569             copyfileobj(fileobj, self.fileobj, tarinfo.size)
    570             blocks, remainder = divmod(tarinfo.size, BLOCKSIZE)
    571             if remainder > 0:
    572                 self.fileobj.write(NUL * (BLOCKSIZE - remainder))
    573                 blocks += 1
    574             self.offset += blocks * BLOCKSIZE
    575 
    576         self.members.append(tarinfo)
    577 
    578     def extractall(self, path=".", members=None):
    579         """Extract all members from the archive to the current working
    580            directory and set owner, modification time and permissions on
    581            directories afterwards. `path' specifies a different directory
    582            to extract to. `members' is optional and must be a subset of the
    583            list returned by getmembers().
    584         """
    585         directories = []
    586 
    587         if members is None:
    588             members = self
    589 
    590         for tarinfo in members:
    591             if tarinfo.isdir():
    592                 # Extract directories with a safe mode.
    593                 directories.append(tarinfo)
    594                 tarinfo = copy.copy(tarinfo)
    595                 tarinfo.mode = 0700
    596             self.extract(tarinfo, path)
    597 
    598         # Reverse sort directories.
    599         directories.sort(key=operator.attrgetter('name'))
    600         directories.reverse()
    601 
    602         # Set correct owner, mtime and filemode on directories.
    603         for tarinfo in directories:
    604             dirpath = os.path.join(path, tarinfo.name)
    605             try:
    606                 self.chown(tarinfo, dirpath)
    607                 self.utime(tarinfo, dirpath)
    608                 self.chmod(tarinfo, dirpath)
    609             except ExtractError, e:
    610                 if self.errorlevel > 1:
    611                     raise
    612                 else:
    613                     self._dbg(1, "tarfile: %s" % e)
    614 
    615     def extract(self, member, path=""):
    616         """Extract a member from the archive to the current working directory,
    617            using its full name. Its file information is extracted as accurately
    618            as possible. `member' may be a filename or a TarInfo object. You can
    619            specify a different directory using `path'.
    620         """
    621         self._check("r")
    622 
    623         if isinstance(member, basestring):
    624             tarinfo = self.getmember(member)
    625         else:
    626             tarinfo = member
    627 
    628         # Prepare the link target for makelink().
    629         if tarinfo.islnk():
    630             tarinfo._link_target = os.path.join(path, tarinfo.linkname)
    631 
    632         try:
    633             self._extract_member(tarinfo, os.path.join(path, tarinfo.name))
    634         except EnvironmentError, e:
    635             if self.errorlevel > 0:
    636                 raise
    637             else:
    638                 if e.filename is None:
    639                     self._dbg(1, "tarfile: %s" % e.strerror)
    640                 else:
    641                     self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename))
    642         except ExtractError, e:
    643             if self.errorlevel > 1:
    644                 raise
    645             else:
    646                 self._dbg(1, "tarfile: %s" % e)
    647 
    648     def extractfile(self, member):
    649         """Extract a member from the archive as a file object. `member' may be
    650            a filename or a TarInfo object. If `member' is a regular file, a
    651            file-like object is returned. If `member' is a link, a file-like
    652            object is constructed from the link's target. If `member' is none of
    653            the above, None is returned.
    654            The file-like object is read-only and provides the following
    655            methods: read(), readline(), readlines(), seek() and tell()
    656         """
    657         self._check("r")
    658 
    659         if isinstance(member, basestring):
    660             tarinfo = self.getmember(member)
    661         else:
    662             tarinfo = member
    663 
    664         if tarinfo.isreg():
    665             return self.fileobject(self, tarinfo)
    666 
    667         elif tarinfo.type not in SUPPORTED_TYPES:
    668             # If a member's type is unknown, it is treated as a
    669             # regular file.
    670             return self.fileobject(self, tarinfo)
    671 
    672         elif tarinfo.islnk() or tarinfo.issym():
    673             if isinstance(self.fileobj, _Stream):
    674                 # A small but ugly workaround for the case that someone tries
    675                 # to extract a (sym)link as a file-object from a non-seekable
    676                 # stream of tar blocks.
    677                 raise StreamError("cannot extract (sym)link as file object")
    678             else:
    679                 # A (sym)link's file object is its target's file object.
    680                 return self.extractfile(self._find_link_target(tarinfo))
    681         else:
    682             # If there's no data associated with the member (directory, chrdev,
    683             # blkdev, etc.), return None instead of a file object.
    684             return None
    685 
    686     def _extract_member(self, tarinfo, targetpath):
    687         """Extract the TarInfo object tarinfo to a physical
    688            file called targetpath.
    689         """
    690         # Fetch the TarInfo object for the given name
    691         # and build the destination pathname, replacing
    692         # forward slashes to platform specific separators.
    693         targetpath = targetpath.rstrip("/")
    694         targetpath = targetpath.replace("/", os.sep)
    695 
    696         # Create all upper directories.
    697         upperdirs = os.path.dirname(targetpath)
    698         if upperdirs and not os.path.exists(upperdirs):
    699             # Create directories that are not part of the archive with
    700             # default permissions.
    701             os.makedirs(upperdirs)
    702 
    703         if tarinfo.islnk() or tarinfo.issym():
    704             self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname))
    705         else:
    706             self._dbg(1, tarinfo.name)
    707 
    708         if tarinfo.isreg():
    709             self.makefile(tarinfo, targetpath)
    710         elif tarinfo.isdir():
    711             self.makedir(tarinfo, targetpath)
    712         elif tarinfo.isfifo():
    713             self.makefifo(tarinfo, targetpath)
    714         elif tarinfo.ischr() or tarinfo.isblk():
    715             self.makedev(tarinfo, targetpath)
    716         elif tarinfo.islnk() or tarinfo.issym():
    717             self.makelink(tarinfo, targetpath)
    718         elif tarinfo.type not in SUPPORTED_TYPES:
    719             self.makeunknown(tarinfo, targetpath)
    720         else:
    721             self.makefile(tarinfo, targetpath)
    722 
    723         self.chown(tarinfo, targetpath)
    724         if not tarinfo.issym():
    725             self.chmod(tarinfo, targetpath)
    726             self.utime(tarinfo, targetpath)
    727 
    728     #--------------------------------------------------------------------------
    729     # Below are the different file methods. They are called via
    730     # _extract_member() when extract() is called. They can be replaced in a
    731     # subclass to implement other functionality.
    732 
    733     def makedir(self, tarinfo, targetpath):
    734         """Make a directory called targetpath.
    735         """
    736         try:
    737             # Use a safe mode for the directory, the real mode is set
    738             # later in _extract_member().
    739             os.mkdir(targetpath, 0700)
    740         except EnvironmentError, e:
    741             if e.errno != errno.EEXIST:
    742                 raise
    743 
    744     def makefile(self, tarinfo, targetpath):
    745         """Make a file called targetpath.
    746         """
    747         source = self.extractfile(tarinfo)
    748         try:
    749             with bltn_open(targetpath, "wb") as target:
    750                 copyfileobj(source, target)
    751         finally:
    752             source.close()
    753 
    754     def makeunknown(self, tarinfo, targetpath):
    755         """Make a file from a TarInfo object with an unknown type
    756            at targetpath.
    757         """
    758         self.makefile(tarinfo, targetpath)
    759         self._dbg(1, "tarfile: Unknown file type %r, " 
    760                      "extracted as regular file." % tarinfo.type)
    761 
    762     def makefifo(self, tarinfo, targetpath):
    763         """Make a fifo called targetpath.
    764         """
    765         if hasattr(os, "mkfifo"):
    766             os.mkfifo(targetpath)
    767         else:
    768             raise ExtractError("fifo not supported by system")
    769 
    770     def makedev(self, tarinfo, targetpath):
    771         """Make a character or block device called targetpath.
    772         """
    773         if not hasattr(os, "mknod") or not hasattr(os, "makedev"):
    774             raise ExtractError("special devices not supported by system")
    775 
    776         mode = tarinfo.mode
    777         if tarinfo.isblk():
    778             mode |= stat.S_IFBLK
    779         else:
    780             mode |= stat.S_IFCHR
    781 
    782         os.mknod(targetpath, mode,
    783                  os.makedev(tarinfo.devmajor, tarinfo.devminor))
    784 
    785     def makelink(self, tarinfo, targetpath):
    786         """Make a (symbolic) link called targetpath. If it cannot be created
    787           (platform limitation), we try to make a copy of the referenced file
    788           instead of a link.
    789         """
    790         if hasattr(os, "symlink") and hasattr(os, "link"):
    791             # For systems that support symbolic and hard links.
    792             if tarinfo.issym():
    793                 if os.path.lexists(targetpath):
    794                     os.unlink(targetpath)
    795                 os.symlink(tarinfo.linkname, targetpath)
    796             else:
    797                 # See extract().
    798                 if os.path.exists(tarinfo._link_target):
    799                     if os.path.lexists(targetpath):
    800                         os.unlink(targetpath)
    801                     os.link(tarinfo._link_target, targetpath)
    802                 else:
    803                     self._extract_member(self._find_link_target(tarinfo), targetpath)
    804         else:
    805             try:
    806                 self._extract_member(self._find_link_target(tarinfo), targetpath)
    807             except KeyError:
    808                 raise ExtractError("unable to resolve link inside archive")
    809 
    810     def chown(self, tarinfo, targetpath):
    811         """Set owner of targetpath according to tarinfo.
    812         """
    813         if pwd and hasattr(os, "geteuid") and os.geteuid() == 0:
    814             # We have to be root to do so.
    815             try:
    816                 g = grp.getgrnam(tarinfo.gname)[2]
    817             except KeyError:
    818                 g = tarinfo.gid
    819             try:
    820                 u = pwd.getpwnam(tarinfo.uname)[2]
    821             except KeyError:
    822                 u = tarinfo.uid
    823             try:
    824                 if tarinfo.issym() and hasattr(os, "lchown"):
    825                     os.lchown(targetpath, u, g)
    826                 else:
    827                     if sys.platform != "os2emx":
    828                         os.chown(targetpath, u, g)
    829             except EnvironmentError, e:
    830                 raise ExtractError("could not change owner")
    831 
    832     def chmod(self, tarinfo, targetpath):
    833         """Set file permissions of targetpath according to tarinfo.
    834         """
    835         if hasattr(os, 'chmod'):
    836             try:
    837                 os.chmod(targetpath, tarinfo.mode)
    838             except EnvironmentError, e:
    839                 raise ExtractError("could not change mode")
    840 
    841     def utime(self, tarinfo, targetpath):
    842         """Set modification time of targetpath according to tarinfo.
    843         """
    844         if not hasattr(os, 'utime'):
    845             return
    846         try:
    847             os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
    848         except EnvironmentError, e:
    849             raise ExtractError("could not change modification time")
    850 
    851     #--------------------------------------------------------------------------
    852     def next(self):
    853         """Return the next member of the archive as a TarInfo object, when
    854            TarFile is opened for reading. Return None if there is no more
    855            available.
    856         """
    857         self._check("ra")
    858         if self.firstmember is not None:
    859             m = self.firstmember
    860             self.firstmember = None
    861             return m
    862 
    863         # Read the next block.
    864         self.fileobj.seek(self.offset)
    865         tarinfo = None
    866         while True:
    867             try:
    868                 tarinfo = self.tarinfo.fromtarfile(self)
    869             except EOFHeaderError, e:
    870                 if self.ignore_zeros:
    871                     self._dbg(2, "0x%X: %s" % (self.offset, e))
    872                     self.offset += BLOCKSIZE
    873                     continue
    874             except InvalidHeaderError, e:
    875                 if self.ignore_zeros:
    876                     self._dbg(2, "0x%X: %s" % (self.offset, e))
    877                     self.offset += BLOCKSIZE
    878                     continue
    879                 elif self.offset == 0:
    880                     raise ReadError(str(e))
    881             except EmptyHeaderError:
    882                 if self.offset == 0:
    883                     raise ReadError("empty file")
    884             except TruncatedHeaderError, e:
    885                 if self.offset == 0:
    886                     raise ReadError(str(e))
    887             except SubsequentHeaderError, e:
    888                 raise ReadError(str(e))
    889             break
    890 
    891         if tarinfo is not None:
    892             self.members.append(tarinfo)
    893         else:
    894             self._loaded = True
    895 
    896         return tarinfo
    897 
    898     #--------------------------------------------------------------------------
    899     # Little helper methods:
    900 
    901     def _getmember(self, name, tarinfo=None, normalize=False):
    902         """Find an archive member by name from bottom to top.
    903            If tarinfo is given, it is used as the starting point.
    904         """
    905         # Ensure that all members have been loaded.
    906         members = self.getmembers()
    907 
    908         # Limit the member search list up to tarinfo.
    909         if tarinfo is not None:
    910             members = members[:members.index(tarinfo)]
    911 
    912         if normalize:
    913             name = os.path.normpath(name)
    914 
    915         for member in reversed(members):
    916             if normalize:
    917                 member_name = os.path.normpath(member.name)
    918             else:
    919                 member_name = member.name
    920 
    921             if name == member_name:
    922                 return member
    923 
    924     def _load(self):
    925         """Read through the entire archive file and look for readable
    926            members.
    927         """
    928         while True:
    929             tarinfo = self.next()
    930             if tarinfo is None:
    931                 break
    932         self._loaded = True
    933 
    934     def _check(self, mode=None):
    935         """Check if TarFile is still open, and if the operation's mode
    936            corresponds to TarFile's mode.
    937         """
    938         if self.closed:
    939             raise IOError("%s is closed" % self.__class__.__name__)
    940         if mode is not None and self.mode not in mode:
    941             raise IOError("bad operation for mode %r" % self.mode)
    942 
    943     def _find_link_target(self, tarinfo):
    944         """Find the target member of a symlink or hardlink member in the
    945            archive.
    946         """
    947         if tarinfo.issym():
    948             # Always search the entire archive.
    949             linkname = "/".join(filter(None, (os.path.dirname(tarinfo.name), tarinfo.linkname)))
    950             limit = None
    951         else:
    952             # Search the archive before the link, because a hard link is
    953             # just a reference to an already archived file.
    954             linkname = tarinfo.linkname
    955             limit = tarinfo
    956 
    957         member = self._getmember(linkname, tarinfo=limit, normalize=True)
    958         if member is None:
    959             raise KeyError("linkname %r not found" % linkname)
    960         return member
    961 
    962     def __iter__(self):
    963         """Provide an iterator object.
    964         """
    965         if self._loaded:
    966             return iter(self.members)
    967         else:
    968             return TarIter(self)
    969 
    970     def _dbg(self, level, msg):
    971         """Write debugging output to sys.stderr.
    972         """
    973         if level <= self.debug:
    974             print >> sys.stderr, msg
    975 
    976     def __enter__(self):
    977         self._check()
    978         return self
    979 
    980     def __exit__(self, type, value, traceback):
    981         if type is None:
    982             self.close()
    983         else:
    984             # An exception occurred. We must not call close() because
    985             # it would try to write end-of-archive blocks and padding.
    986             if not self._extfileobj:
    987                 self.fileobj.close()
    988             self.closed = True
    989 # class TarFile
    990 
    991 TarFile
    tarfile的源代码
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import tarfile
     7 tar = tarfile.open("yinzhengjie.tar","w")
     8 tar.add(r"D:pythondaimaDAY5day5.zip",arcname="day5.zip") 
     9 tar.add(r"D:pythondaimaDAY3学生信息.xlsx",arcname="test_11") #相当于将“学生信息.xlsx”这个文件重命名为"test_11"并添加到压缩文件“yinzhengjie.tar”中
    10 tar.close() 
    tarfile压缩的用法
    1 #!/usr/bin/env python
    2 #_*_coding:utf-8_*_
    3 #@author :yinzhengjie
    4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
    5 #EMAIL:y1053419035@qq.com
    6 import tarfile
    7 tar = tarfile.open("yinzhengjie.tar","r") #注意解压的时候,打开的模式应该是"r",而不是"w"哟!
    8 tar.extractall(path=r"D:pythondaimaDAY6	est")   #其中的path表示设置的解压后的存放地址
    9 tar.close()
    tarfile解压的用法

    8.shelve模块

      它是对pickle的上层封装,比pickle用起来更简单,shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import shelve
     7 f = shelve.open('shelve_test')  # 打开一个文件
     8 class Test(object):
     9     def __init__(self, n):
    10         self.n = n
    11 def func():
    12     print("my name is yinzhengjie!")
    13 t = Test(123)
    14 name = ["yinzhengjie", "lijing", "test"]
    15 f["first"] = name  # 序列化列表
    16 f["second"] = t  # 序列化类,注意只是序列化的类名,如果想要在新的操作系统中调用的话,需要导入哟!
    17 f["third"] = func #序列化函数,注意只是序列化的函数名,如果想要在新的操作系统中调用的话,需要导入哟!
    18 f.close()
    序列化数据
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import shelve
     7 f = shelve.open('shelve_test')
     8 for i in f.keys(): 
     9     print(i)
    10 print(f.get("first")) #相当于load,取得里面的数据,但是如果要读取类或者函数的话需要导入相应的模块哟!
    11 
    12 
    13 #以上代码执行结果如下:
    14 first
    15 second
    16 third
    17 ['yinzhengjie', 'lijing', 'test']
    反序列化数据

    9.xml模块

      xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

      xml的格式如下,就是通过<>节点来区别数据结构的:

     1 <?xml version="1.0"?>
     2 <data>
     3     <country name="Liechtenstein">
     4         <rank updated="yes">2</rank>
     5         <year>2008</year>
     6         <gdppc>141100</gdppc>
     7         <neighbor name="Austria" direction="E"/>
     8         <neighbor name="Switzerland" direction="W"/>
     9         <hotspots>
    10             <test1>维也纳</test1>
    11             <test2>萨尔斯堡</test2>
    12         </hotspots>
    13     </country>
    14     <country name="Singapore">
    15         <rank updated="yes">5</rank>
    16         <year>2011</year>
    17         <gdppc>59900</gdppc>
    18         <neighbor name="Malaysia" direction="N"/>
    19     </country>
    20     <country name="Panama">
    21         <rank updated="yes">69</rank>
    22         <year>2011</year>
    23         <gdppc>13600</gdppc>
    24         <neighbor name="Costa Rica" direction="W"/>
    25         <neighbor name="Colombia" direction="E"/>
    26     </country>
    27 </data>
    xmltest.xml
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import xml.etree.ElementTree as ET
     7 tree = ET.parse("xmltest.xml") #解析(可以理解为打开一个文件)
     8 root = tree.getroot() #找到根节点
     9 print(root.tag)  #打印根节点的名字
    10 # 遍历xml文档
    11 print("*"*50,"我是分割线","*"*50)
    12 for child in root:
    13     print(child.tag, child.attrib) #打印前者子节点的名字“country”,并打印其属性。
    14     for i in child:
    15         print(i.tag, i.text,i.attrib) #打印子节点的参数名,已经其所对应的值,最后打印其属性。
    16 # 只遍历year 节点
    17 print("*" * 50, "我是分割线", "*" * 50)
    18 for node in root.iter('year'):
    19     print(node.tag, node.text)
    20 
    21 # 只遍历country节点
    22 print("*" * 50, "我是分割线", "*" * 50)
    23 for node in root.iter('country'):
    24     print(node.tag, node.text,node.attrib)
    25 
    26 print("*" * 50, "我是分割线", "*" * 50)
    27 for node in root.iter('test1'):
    28     print(node.tag, node.text,node.attrib)
    29 
    30 
    31 #以上代码执行结果如下:
    32 data
    33 ************************************************** 我是分割线 **************************************************
    34 country {'name': 'Liechtenstein'}
    35 rank 2 {'updated': 'yes'}
    36 year 2008 {}
    37 gdppc 141100 {}
    38 neighbor None {'direction': 'E', 'name': 'Austria'}
    39 neighbor None {'direction': 'W', 'name': 'Switzerland'}
    40 hotspots 
    41              {}
    42 country {'name': 'Singapore'}
    43 rank 5 {'updated': 'yes'}
    44 year 2011 {}
    45 gdppc 59900 {}
    46 neighbor None {'direction': 'N', 'name': 'Malaysia'}
    47 country {'name': 'Panama'}
    48 rank 69 {'updated': 'yes'}
    49 year 2011 {}
    50 gdppc 13600 {}
    51 neighbor None {'direction': 'W', 'name': 'Costa Rica'}
    52 neighbor None {'direction': 'E', 'name': 'Colombia'}
    53 ************************************************** 我是分割线 **************************************************
    54 year 2008
    55 year 2011
    56 year 2011
    57 ************************************************** 我是分割线 **************************************************
    58 country 
    59          {'name': 'Liechtenstein'}
    60 country 
    61          {'name': 'Singapore'}
    62 country 
    63          {'name': 'Panama'}
    64 ************************************************** 我是分割线 **************************************************
    65 test1 维也纳 {}
    查看xml的方法
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import xml.etree.ElementTree as ET
     7 tree = ET.parse("xmltest.xml")
     8 root = tree.getroot()
     9 # 修改
    10 for node in root.iter('year'): #表示操作的对象是“year”字段
    11     new_year = int(node.text) + 1  #将年份加“1”
    12     node.text = str(new_year)  #把数字转换成字符串
    13     node.set("updated", "yes")  #set是更改属性,增加了一个属性updated="yes"
    14 tree.write("xmltest2.xml",encoding="utf-8") #将修改后的内容写入xml文件中。
    修改xml文件的属性
     1 <data>
     2     <country name="Liechtenstein">
     3         <rank updated="yes">2</rank>
     4         <year updated="yes">2009</year>
     5         <gdppc>141100</gdppc>
     6         <neighbor direction="E" name="Austria" />
     7         <neighbor direction="W" name="Switzerland" />
     8         <hotspots>
     9             <test1>维也纳</test1>
    10             <test2>萨尔斯堡</test2>
    11         </hotspots>
    12     </country>
    13     <country name="Singapore">
    14         <rank updated="yes">5</rank>
    15         <year updated="yes">2012</year>
    16         <gdppc>59900</gdppc>
    17         <neighbor direction="N" name="Malaysia" />
    18     </country>
    19     <country name="Panama">
    20         <rank updated="yes">69</rank>
    21         <year updated="yes">2012</year>
    22         <gdppc>13600</gdppc>
    23         <neighbor direction="W" name="Costa Rica" />
    24         <neighbor direction="E" name="Colombia" />
    25     </country>
    26 </data>
    xmltest2.xml
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import xml.etree.ElementTree as ET
     7 tree = ET.parse("xmltest.xml")
     8 root = tree.getroot()
     9 # 删除node
    10 for country in root.findall('country'):
    11     rank = int(country.find('rank').text)
    12     if rank > 50: #如果国家排名大于50就删除这个国家
    13         root.remove(country)
    14 tree.write('output.xml',encoding="utf-8")
    删除xml文件的方法
     1 <data>
     2     <country name="Liechtenstein">
     3         <rank updated="yes">2</rank>
     4         <year>2008</year>
     5         <gdppc>141100</gdppc>
     6         <neighbor direction="E" name="Austria" />
     7         <neighbor direction="W" name="Switzerland" />
     8         <hotspots>
     9             <test1>维也纳</test1>
    10             <test2>萨尔斯堡</test2>
    11         </hotspots>
    12     </country>
    13     <country name="Singapore">
    14         <rank updated="yes">5</rank>
    15         <year>2011</year>
    16         <gdppc>59900</gdppc>
    17         <neighbor direction="N" name="Malaysia" />
    18     </country>
    19     </data>
    output.xml
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import xml.etree.ElementTree as ET
     7 new_xml = ET.Element("namelist")  #生成一个根节点
     8 name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})  #SubElement创建了一个子节点,其中名字叫“name”,属性是{"enrolled": "yes"}
     9 age = ET.SubElement(name, "age", attrib={"checked": "no"}) #在name下又创建了一个子节点
    10 sex = ET.SubElement(name, "sex")
    11 sex.text = '33'
    12 
    13 name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
    14 age = ET.SubElement(name2, "age")
    15 age.text = '19'
    16 et = ET.ElementTree(new_xml)  # 生成文档对象
    17 et.write("test.xml", encoding="utf-8", xml_declaration=True)
    18 # ET.dump(new_xml)  # 打印生成的格式
    创建xml文件的方法
    1 <?xml version='1.0' encoding='utf-8'?>
    2 <namelist>
    3     <name enrolled="yes">
    4         <age checked="no" />
    5         <sex>33</sex></name>
    6     <name enrolled="no">
    7         <age>19</age>
    8     </name>
    9 </namelist>
    test.xml
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import xml.etree.ElementTree as ET
     7 tree = ET.parse("xmltest.xml")
     8 root = tree.getroot()
     9 for country in root.findall('country'):
    10    rank = int(country.find('rank').text)
    11    if rank > 50:
    12      root.remove(country)
    13    else:
    14        sub_ele = ET.SubElement(country,"population",attrib={"enrolled":"yes"})  #创建一个新的“population”
    15        sub_ele.text = str(100000000000)
    16 tree.write('output2.xml')
    在原xml的基础上新增文件内容
     1 <data>
     2     <country name="Liechtenstein">
     3         <rank updated="yes">2</rank>
     4         <year>2008</year>
     5         <gdppc>141100</gdppc>
     6         <neighbor direction="E" name="Austria" />
     7         <neighbor direction="W" name="Switzerland" />
     8         <hotspots>
     9             <test1>&#32500;&#20063;&#32435;</test1>
    10             <test2>&#33832;&#23572;&#26031;&#22561;</test2>
    11         </hotspots>
    12     <population enrolled="yes">100000000000</population></country>
    13     <country name="Singapore">
    14         <rank updated="yes">5</rank>
    15         <year>2011</year>
    16         <gdppc>59900</gdppc>
    17         <neighbor direction="N" name="Malaysia" />
    18     <population enrolled="yes">100000000000</population></country>
    19     </data>
    output2.xml

    10.PyYAML模块

    请参考官网:http://pyyaml.org/wiki/PyYAMLDocumentation

     saltstack自动化运维工具的配置文件就是要ongodb这种格式写的。

    11.ConfigParser模块

       用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变更为 configparser。类似于apache和mysql的配置文件就用这个模块生成的。

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import configparser
     7 config = configparser.ConfigParser()  #生成一个根节点实例
     8 config["DEFAULT"] = {'ServerAliveInterval': '45',
     9                      'Compression': 'yes',
    10                      'CompressionLevel': '9'}
    11 config['bitbucket.org'] = {}  #生成一个空的字典·
    12 config['bitbucket.org']['User'] = 'yinzhengjie'  #往这个空字典中添加信息
    13 config['topsecret.server.com'] = {}  #通过config实例生成一个叫“topsecret.server.com”的空节点
    14 topsecret = config['topsecret.server.com']  #找到上面那个空节点然后赋值给一个变量,之后可以往里面赋值参数
    15 topsecret['Host Port'] = '50022'  # mutates the parser
    16 topsecret['ForwardX11'] = 'no'  # same here
    17 config['DEFAULT']['ForwardX11'] = 'yes' #给“DEFAULT”字段赋值
    18 with open('example.ini', 'w') as configfile: #最终将数据写入到“example.ini”文件中.
    19     config.write(configfile)
    自动生成一个configparser文件
     1 [DEFAULT]
     2 compressionlevel = 9
     3 serveraliveinterval = 45
     4 compression = yes
     5 forwardx11 = yes
     6 
     7 [bitbucket.org]
     8 user = yinzhengjie
     9 
    10 [topsecret.server.com]
    11 host port = 50022
    12 forwardx11 = no
    example.ini
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import configparser
     7 config = configparser.ConfigParser() #生成一个实例
     8 print(config.sections())  #打印出有多少个子配置实例
     9 print("*"*50,"我是分割线","*"*50)
    10 print(config.read('example.ini')) #读取这个文件
    11 print("*"*50,"我是分割线","*"*50)
    12 print(config.sections())  #打印出有多少个子配置实例,当read到数据之后,就可以看到相关的子实例,并且默认不打印“[DEFAULT]”这个子实例。
    13 print("*"*50,"我是分割线","*"*50)
    14 print('bitbucket.org' in config)  #取布尔值,判断bitbucket.org是否在config这个实例中。
    15 print('bytebong.com' in config)
    16 print("*"*50,"我是分割线","*"*50)
    17 print(config['bitbucket.org']['User'])  #取“config['bitbucket.org']"子实例中的'User'变量所对应的值
    18 print("*"*50,"我是分割线","*"*50)
    19 print(config['DEFAULT']['Compression'])
    20 topsecret = config['topsecret.server.com']
    21 print(topsecret['ForwardX11'])
    22 print("*"*50,"我是分割线","*"*50)
    23 for key in config['bitbucket.org']: #遍历出'bitbucket.org'子实例中的变量
    24     print(key)
    25 print(config['bitbucket.org']['ForwardX11'])
    configparser查询用法实例
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import configparser
     7 config = configparser.ConfigParser() #生成一个实例
     8 config.read('example.ini')  #读取这个文件,注意,如果缺少这个步骤,无法进行修改或者读取哟!
     9 config.set("bitbucket.org","name","Yinzhengjie")  #在bitbucket.org的sections添加"name"的值为"Yinzhengjie"
    10 config.set("bitbucket.org","user","尹正杰")   #在bitbucket.org的sections修改"user"的值为"尹正杰"
    11 config.write(open("test_1.cfg","w",encoding="utf-8"))
    configparser修改和新增的实例
     1 [DEFAULT]
     2 compressionlevel = 9
     3 serveraliveinterval = 45
     4 compression = yes
     5 forwardx11 = yes
     6 
     7 [bitbucket.org]
     8 user = 尹正杰
     9 name = Yinzhengjie
    10 
    11 [topsecret.server.com]
    12 host port = 50022
    13 forwardx11 = no
    test_1.cfg
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import configparser
     7 config = configparser.ConfigParser() #生成一个实例
     8 config.read('example.ini')
     9 config.remove_section("bitbucket.org")  #删除整个section!
    10 config.remove_option("DEFAULT","forwardx11")  #删除某个section的一个子项,
    11 config.write(open("test_rm.ini","w",encoding="utf-8")) #如果有汉子的话需要制定编码格式才能正常打印汉子哟~
    configparser删除的实例
    1 [DEFAULT]
    2 compressionlevel = 9
    3 serveraliveinterval = 45
    4 compression = yes
    5 
    6 [topsecret.server.com]
    7 host port = 50022
    8 forwardx11 = no
    test_rm.ini

    12.hashlib模块

      用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法.

    1>.MD5算法参数详解:

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import hashlib
     7 m = hashlib.md5()
     8 m.update(b"hello") #字节格式输入
     9 print(m.hexdigest()) #用十六进制输出一段md5值,注意,只要输入的值不变,这个值就不会变的!
    10 m.update(b"my name is yinzhengjie")
    11 print(m.hexdigest())
    12 
    13 #注意,将上面两个字段拼接起来,其中的MD5值也是会发生变化的
    14 m2 = hashlib.md5()
    15 m2.update(b"hello  my name is yinzhengjie")
    16 print(m2.hexdigest())
    17 
    18 '''
    19 扩展:
    20     MD5值是无法被反解的,网上有人说能破解是骗人的,之所以能破解,是因为他们已经将算好的md5值存入到数据库中,然后跟你你输入的MD5值给你返回一个明文的字符串。
    21 '''
    22 
    23 
    24 #以上代码执行结果如下:
    25 5d41402abc4b2a76b9719d911017c592
    26 1c7bdaafeb36ea7e3236d01afeee39cf
    27 1d19d8f2d5037b0f3e9a2d020930ba91
    十六进制md5算法实例展示
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import hashlib
     7 m = hashlib.md5()
     8 m.update(b"hello") #字节格式输入
     9 print(m.digest()) #用十六进制输出一段md5值,注意,只要输入的值不变,这个值就不会变的!
    10 m.update(b"my name is yinzhengjie")
    11 print(m.digest())
    12 
    13 #注意,将上面两个字段拼接起来,其中的MD5值也是会发生变化的
    14 m2 = hashlib.md5()
    15 m2.update(b"hello  my name is yinzhengjie")
    16 print(m2.digest())
    17 
    18 '''
    19 扩展:
    20     MD5值是无法被反解的,网上有人说能破解是骗人的,之所以能破解,是因为他们已经将算好的md5值存入到数据库中,然后跟你你输入的MD5值给你返回一个明文的字符串。
    21 '''
    22 
    23 #以上代码执行结果如下:
    24 b']A@*xbcK*vxb9qx9dx91x10x17xc5x92'
    25 b'x1c{xdaxafxeb6xea~26xd0x1axfexee9xcf'
    26 b'x1dx19xd8xf2xd5x03{x0f>x9a-x02	0xbax91'
    二进制md5算法实例展示

    2>.sha1算法参数详解:

      Google已经将改算法破解了,只是还没有公布,目前很少人用这种算法了!

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import hashlib
     7 m = hashlib.sha1()
     8 m.update(b"hello") #字节格式输入
     9 print(m.digest()) #用十六进制输出一段md5值,注意,只要输入的值不变,这个值就不会变的!
    10 m.update(b"my name is yinzhengjie")
    11 print(m.digest())
    12 
    13 #注意,将上面两个字段拼接起来,其中的MD5值也是会发生变化的
    14 m2 = hashlib.sha1()
    15 m2.update(b"hello  my name is yinzhengjie")
    16 print(m2.digest())
    17 
    18 '''
    19 扩展:
    20     MD5值是无法被反解的,网上有人说能破解是骗人的,之所以能破解,是因为他们已经将算好的md5值存入到数据库中,然后跟你你输入的MD5值给你返回一个明文的字符串。
    21 '''
    22 
    23 #以上代码执行结果如下:
    24 b'xaaxf4xc6x1dxdcxc5xe8xa2xdaxbexdex0f;H,xd9xaexa9CM'
    25 b'pxffxe5<x08xb9D?xabJxcdC2fx84xa07xd6xc2c'
    26 b'xadx06x8bx91)x1c x99x82*6D^xb2DAx12_3xa6'
    二进制sha1算法实例展示
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import hashlib
     7 m = hashlib.sha1()
     8 m.update(b"hello") #字节格式输入
     9 print(m.hexdigest()) #用十六进制输出一段md5值,注意,只要输入的值不变,这个值就不会变的!
    10 m.update(b"my name is yinzhengjie")
    11 print(m.hexdigest())
    12 
    13 #注意,将上面两个字段拼接起来,其中的MD5值也是会发生变化的
    14 m2 = hashlib.sha1()
    15 m2.update(b"hello  my name is yinzhengjie")
    16 print(m2.hexdigest())
    17 
    18 '''
    19 扩展:
    20     MD5值是无法被反解的,网上有人说能破解是骗人的,之所以能破解,是因为他们已经将算好的md5值存入到数据库中,然后跟你你输入的MD5值给你返回一个明文的字符串。
    21 '''
    22 
    23 
    24 #以上代码执行结果如下:
    25 aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
    26 70ffe53c08b9443fab4acd43326684a037d6c263
    27 ad068b91291c2099822a36445eb24441125f33a6
    十六进制sha1算法实例展示

    3>.sha256算法参数详解:

      这个是没有被破解的,连谷歌破解的仅仅是sha1,而256加密后的明显字节变成啊,有木有。

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import hashlib
     7 m = hashlib.sha256()
     8 m.update(b"hello") #字节格式输入
     9 print(m.digest()) #用十六进制输出一段md5值,注意,只要输入的值不变,这个值就不会变的!
    10 m.update(b"my name is yinzhengjie")
    11 print(m.digest())
    12 
    13 #注意,将上面两个字段拼接起来,其中的MD5值也是会发生变化的
    14 m2 = hashlib.sha256()
    15 m2.update(b"hello  my name is yinzhengjie")
    16 print(m2.digest())
    17 
    18 
    19 #以上代码执行结果如下:
    20 b',xf2Mxba_xb0xa3x0e&xe8;*xc5xb9xe2x9ex1bx16x1e\x1fxa7B^sx043bx93x8bx98$'
    21 b'xecxf6x8ex01x17xac!:xb9<xe4xabxeex13x03xccxe4rxb0xdcxfbxcbmxd4xecxa2xc9Px02xfdixb7'
    22 b'xf4x9dxe7oxe3x01Axf28xd0xc1b4xa0xbfx01x88xbfx9a4xb4xe8xddxb6\Px8c&xd5xb1xafx06'
    二进制sha256算法实例展示
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import hashlib
     7 m = hashlib.sha256()
     8 m.update(b"hello") #字节格式输入
     9 print(m.hexdigest()) #用十六进制输出一段md5值,注意,只要输入的值不变,这个值就不会变的!
    10 m.update(b"my name is yinzhengjie")
    11 print(m.hexdigest())
    12 
    13 #注意,将上面两个字段拼接起来,其中的MD5值也是会发生变化的
    14 m2 = hashlib.sha256()
    15 m2.update(b"hello  my name is yinzhengjie")
    16 print(m2.hexdigest())
    17 
    18 
    19 #以上代码执行结果如下:
    20 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
    21 ecf68e0117ac213ab93ce4abee1303cce472b0dcfbcb6dd4eca2c95002fd69b7
    22 f49de76fe30141f238d0c16234a0bf0188bf9a34b4e8ddb65c508c26d5b1af06
    十六进制sha256算法实例展示

    4>.sha512算法参数详解:

      这个也没有破解,明显的效果就是加密后的值变的比256还要长呢!

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import hashlib
     7 m = hashlib.sha512()
     8 m.update(b"hello") #字节格式输入
     9 print(m.digest()) #用十六进制输出一段md5值,注意,只要输入的值不变,这个值就不会变的!
    10 m.update(b"my name is yinzhengjie")
    11 print(m.digest())
    12 
    13 #注意,将上面两个字段拼接起来,其中的MD5值也是会发生变化的
    14 m2 = hashlib.sha512()
    15 m2.update(b"hello  my name is yinzhengjie")
    16 print(m2.digest())
    17 
    18 
    19 #以上代码执行结果如下:
    20 b'x9bqxd2$xbdbxf3x]x96xd4jxd3xea=s1x9bxfbxc2x89x0cxaaxdaxe2xdfxf7%x19g<xa7##xc3xd9x9bxa5xc1x1d|zxccnx14xb8xc5xdax0cFcG\.\:xdexf4osxbcxdexc0C'
    21 b"7x8fbxe6'x11xccxa8Ix9bx89=xcfxacx06xdcxbcxb7GyGx96xd9=xfcxa7rxc6xbax9epx96xd7Xx05x82xbdx87xaex94x90UDxddxdfx94-xa5xcdxf9ox89xdcxcfx85prx9ekvEx12xccx0f"
    22 b'xeax1bxdaxce3r>x83x98x94xd7x7fpxad}x84wxb3oxd2xf4ZMBxb6xb9c|t]xa5xf7]*xb2vxf10xa8&x19xebxc7xe5;x9d0x92ox9bxa8x91vxc5x03xd4x82Zxb3;xea[x01h'
    二进制sha512算法实例展示
     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import hashlib
     7 m = hashlib.sha512()
     8 m.update(b"hello") #字节格式输入
     9 print(m.hexdigest()) #用十六进制输出一段md5值,注意,只要输入的值不变,这个值就不会变的!
    10 m.update(b"my name is yinzhengjie")
    11 print(m.hexdigest())
    12 
    13 #注意,将上面两个字段拼接起来,其中的MD5值也是会发生变化的
    14 m2 = hashlib.sha512()
    15 m2.update(b"hello  my name is yinzhengjie")
    16 print(m2.hexdigest())
    17 
    18 
    19 #以上代码执行结果如下:
    20 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043
    21 378f62e62711cca8499b893dcfac06dcbcb747794796d93dfca772c6ba9e7096d7580582bd87ae94905544dddf942da5cdf96f89dccf8570729e6b764512cc0f
    22 ea1bdace33723e839894d77f70ad7d8477b36fd2f45a4d42b6b9637c745da5f75d2ab276f130a82619ebc7e53b9d30926f9ba89176c503d4825ab33bea5b0168
    十六进制sha512算法实例展示

    5>.hmac模块

      如果你觉得以上的加密方法还是不够安全~厉害了,你的安全感可真低啊,看来是伤的不轻,一定是一个有故事的人,不过针对你这种人呢~还有一种算法为你特别定制hmac,等你成为了一个开发大神,你可以自己写一个算法,因为你毕竟只相信你自己嘛,哈哈~

      散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了。(它内部对我们创建 key 和 内容 再进行处理然后再加密)

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import hmac
     7 h = hmac.new("我本有心向明月".encode("utf-8"), "奈何明月照沟渠".encode("utf-8"),) #"我本有心向明月"这就好比双方(A,B)已经约定好了的key,(类似于我们第一次登录linux服务器,使用ssh登陆方式都会提示你,让你输入"yes"后才能输入密码。),接受者(A)接收到了"奈何明月照沟渠"这个明文消息和加密后的字符“489f9932949514ab24894559150088c0”,然后用定义好的key和去加密"奈何明月照沟渠"这个明文字符,如果加密后生成的字符是“489f9932949514ab24894559150088c0”就证明这个消息是发送者(B)发送过来的数据,它只能验证消息的合法来源。如果中间人截获了明文消息加以修改的,就会被发现!
     8 print(h.hexdigest())
     9 
    10 
    11 #以上代码执行结果如下:
    12 489f9932949514ab24894559150088c0
    hmac算法实例展示

    13.subproces模块

      subproces基本上就是为了取代os.system和os.spawn*模块的。

    1>.subprocess.run调用shell命令,只能保存执行后的状态,不能保存命令的执行结果!

     1 #不含参数的调用linux命令的方法
     2 >>> a = subprocess.run("df")                               
     3 Filesystem     1K-blocks    Used Available Use% Mounted on
     4 /dev/sda2        8854456 4170968   4227040  50% /
     5 tmpfs             502172     228    501944   1% /dev/shm
     6 /dev/sda1         289293   28463    245470  11% /boot
     7 
     8 #含参数的调用linux命令的方法
     9 >>> a = subprocess.run(["df","-h"])
    10 Filesystem      Size  Used Avail Use% Mounted on
    11 /dev/sda2       8.5G  3.8G  4.3G  48% /
    12 tmpfs           491M  228K  491M   1% /dev/shm
    13 /dev/sda1       283M   28M  240M  11% /boot
    14 >>> 
    15 
    16 
    17 
    18 #调用复杂的linux命令的方法,需要加“shell=True”,表示将前面引号的内容放在一个终端(terminal)去执行,需要注意的是这个不能保存命令输出的结果,而是保存命令执行的结果哟!一般非“0”就表示命令没有执行成功,而结果是“0”表示执行命令实成功的,但是命令的输出结果是无法保存的!切记!
    19 >>> a = subprocess.run("df -h | grep /dev/sda1",shell=True)
    20 /dev/sda1       283M   28M  240M  11% /boot
    21 >>> a.returncode
    22 0
    subprocess.run实例

    2>.执行命令,返回命令的执行状态,“0” or 非 “0”

     1 #执行命令,返回命令执行状态 , 0 or 非0
     2 >>> retcode = subprocess.call(["ls", "-l"])
     3 total 96
     4 -rw-------. 1 root root  3321 Oct 13 10:26 anaconda-ks.cfg
     5 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Desktop
     6 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Documents
     7 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Downloads
     8 -rw-r--r--. 1 root root 41433 Oct 13 10:26 install.log
     9 -rw-r--r--. 1 root root  9154 Oct 13 10:24 install.log.syslog
    10 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Music
    11 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Pictures
    12 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Public
    13 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Templates
    14 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Videos
    15 >>>
    16 
    17 
    18 #执行命令,如果命令结果为0,就正常返回,否则抛异常
    19 >>> subprocess.check_call(["ls", "-l"])    
    20 total 96
    21 -rw-------. 1 root root  3321 Oct 13 10:26 anaconda-ks.cfg
    22 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Desktop
    23 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Documents
    24 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Downloads
    25 -rw-r--r--. 1 root root 41433 Oct 13 10:26 install.log
    26 -rw-r--r--. 1 root root  9154 Oct 13 10:24 install.log.syslog
    27 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Music
    28 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Pictures
    29 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Public
    30 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Templates
    31 drwxr-xr-x. 2 root root  4096 Oct 13 22:03 Videos
    32 0
    33 >>>
    subprocess.call与subprocess.check_call函数的调用方法

    3>.接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果

    1 >>> subprocess.getstatusoutput('ls /bin/pwd')
    2 (0, '/bin/pwd')
    3 >>> 
    subprocess.getstatusoutput函数的调用方法

    4>.接收字符串格式命令,并返回结果

    1 >>> subprocess.getoutput('ifconfig | grep eth0')
    2 'eth0      Link encap:Ethernet  HWaddr 00:0C:29:D4:DB:87  '
    3 >>> 
    subprocess.getoutput函数调用方法

    5>.执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res

    1 >>> res=subprocess.check_output(['pwd'])    
    2 >>> res
    3 b'/root
    '
    4 >>> 
    subprocess.check_output函数调用方法

     6>.上面那些方法,底层都是封装的subprocess.Popen

     1 >>> p = subprocess.Popen("df -h|grep /dev/sda1",stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
     2 >>> p.stdout.read()
     3 b'/dev/sda1       283M   28M  240M  11% /boot
    '
     4 >>> 
     5 
     6 “”“
     7 注意:
     8 我们来对第一行的进行讲解一下
     9 subprocess.Popen表示打开一个终端(只是启动一个进程),stdin=subprocess.PIPE表示输入通过subprocess.PIPE这个管道传输,stdout=subprocess.PIPE表示输出也通过subprocess.PIPE这个管道传输,stderr=subprocess.PIPE同理。
    10 ”“”
    subprocess.Popen函数用法

    7>.检查命令是否执行完毕

     1 >>> p = subprocess.Popen("top -bn 5",stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
     2 >>> p.poll()
     3 >>> p.poll()
     4 >>> p.poll()
     5 >>> p.poll()
     6 >>> p.poll()
     7 >>> p.poll()
     8 0
     9 >>> p.poll()
    10 0
    11 >>> 
    12 ‘’‘
    13 poll()
    14 Check if child process has terminated. Returns returncode
    15 ’‘’
    poll()方法调用案例【不需要等】
    1 >>> p = subprocess.Popen("top -bn 5",stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
    2 >>> p.wait()
    3 0
    4 >>> 
    5 
    6 '''
    7 wait()
    8 Wait for child process to terminate. Returns returncode attribute.
    9 '''
    wait()方法调用案例【需要等】返回执行状态
    1 >>> p = subprocess.Popen("top -bn 5",stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True) 
    2 >>> p.poll()
    3 >>> p.terminate()
    4 >>> p.poll()     
    5 143
    6 
    7 '''
    8 terminate() 杀掉所启动进程,此时p.poll返回值应该是非“0”,因为不是正常结束的!没有执行完毕就被杀掉了。
    9 '''
    terminate()方法调用案例,直接杀掉启动进程
     1 >>> p = subprocess.Popen("df -h;sleep 100",stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
     2 >>> p.poll()       
     3 >>> p.poll()
     4 >>> p.communicate(timeout=2)
     5 Traceback (most recent call last):
     6   File "<stdin>", line 1, in <module>
     7   File "/usr/local/lib/python3.5/subprocess.py", line 1068, in communicate
     8     stdout, stderr = self._communicate(input, endtime, timeout)
     9   File "/usr/local/lib/python3.5/subprocess.py", line 1699, in _communicate
    10     self._check_timeout(endtime, orig_timeout)
    11   File "/usr/local/lib/python3.5/subprocess.py", line 1094, in _check_timeout
    12     raise TimeoutExpired(self.args, orig_timeout)
    13 subprocess.TimeoutExpired: Command 'df -h;sleep 100' timed out after 2 seconds
    14 >>> 
    15 
    16 ‘’‘
    17 communicate() 等待任务结束,我们需要在里面添加一个参数,默认单位是“s”,如果程序执行时间超过指定的时间就会抛出一个“TimeoutExpired”的字样哟,不过我们可以用异常处理来吧这个错误解决掉!
    18 ’‘’
    communicate()函数调用方法 
     1 >>> def name():
     2 ...     print("my name is yinzhengjie!")
     3 ... 
     4 >>> p = subprocess.Popen("pwd",stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE, preexec_fn=name)    >>> p.stdout.read()
     5 b'my name is yinzhengjie!
    /root
    '
     6 >>> 
     7 
     8 ‘’‘
     9 preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用,运行结果见上例。
    10 ’‘’
    preexec_fn参数调用案例
    1 >>> p = subprocess.Popen("pwd",cwd="/usr/local",stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)  
    2 >>> p.stdout.read()
    3 b'/usr/local
    '
    4 >>> 
    5 
    6 '''
    7 cwd:用于设置子进程的当前目录
    8 '''
    cwd参数调用案例
    1 >>> p = subprocess.Popen("echo $name_str",cwd="/usr/local",shell=True,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,env={"name_str":"yinzhengjie"})
    2 >>> p.stdout.read()
    3 b'yinzhengjie
    '
    4 >>> 
    5 ‘’‘
    6 提示:
    7 env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
    8 ’‘’
    env参数调用案例

    14.re模块

      正在表达式主要是用于模糊匹配,Python中的正则用法比较简单,但是规则比较麻烦,你可以根据你的需求配置不同的规则

    常用正则表达式符号:

    1 'A'    只从字符开头匹配,re.search("Yin","yinzhengjie") 是匹配不到的
    2 ''    匹配字符结尾,同$
    3 'd'    匹配数字0-9
    4 'D'    匹配非数字
    5 'w'    匹配[A-Za-z0-9]
    6 'W'    匹配非[A-Za-z0-9]
    7 's'     匹配空白字符、	、
    、
     , re.search("s+","ab	c1
    3").group() 结果 '	'
    1 re.match 从头开始匹配
    2 re.search 匹配包含
    3 re.findall 把所有匹配到的字符放到以列表中的元素返回
    4 re.splitall 以匹配到的字符当做列表分隔符
    5 re.sub      匹配字符并替换
    最常用的匹配语法

    1>.'.'     默认匹配除 之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.match("yin","yinzhengjie"))  #精确匹配,前面是条件,后面是内容
     8 print(re.match(".","yinzhengjie"))  #模糊匹配单个字符
     9 print(re.match("...","yinzhengjie"))
    10 print(re.match("....","yin
    zhengjie"))  #从开头开始模糊匹配4个字符,无法识别换行符"
    ",
    11 
    12 
    13 #以上代码执行结果如下:
    14 <_sre.SRE_Match object; span=(0, 3), match='yin'>
    15 <_sre.SRE_Match object; span=(0, 1), match='y'>
    16 <_sre.SRE_Match object; span=(0, 3), match='yin'>
    17 None
    '.' 的用法展示

    2>.'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a"," abc eee",flags=re.MULTILINE)

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.match("^Y","Yinzhengjie"))
     8 print(re.match("jie","Yinzhengjie")) #表示从头开始匹配
     9 print(re.search("jie","yinzhengjie"))  #表示匹配包含
    10 
    11 
    12 
    13 #以上代码执行结果如下:
    14 <_sre.SRE_Match object; span=(0, 1), match='Y'>
    15 None
    16 <_sre.SRE_Match object; span=(8, 11), match='jie'>
    '^'的用法展示

    3>.'$'     匹配字符结尾,或e.search("foo$","bfoo sdfsf",flags=re.MULTILINE).group()也可以

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("jie$","Yinzhengjie")) #匹配包含,不从开头开始匹配哟
     8 
     9 
    10 #以上代码执行结果如下:
    11 <_sre.SRE_Match object; span=(8, 11), match='jie'>
    $'用法展示

    4>.'+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab''abb']

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.match(".+","Yinzhengjie")) #表示从头开始匹配
     8 print(re.match("^.+","Yinzhengjie"))
     9 print(re.match(".+","Yinzheng
    jie")) #表示匹配包含
    10 
    11 
    12 
    13 #以上代码执行结果如下:
    14 <_sre.SRE_Match object; span=(0, 11), match='Yinzhengjie'>
    15 <_sre.SRE_Match object; span=(0, 11), match='Yinzhengjie'>
    16 <_sre.SRE_Match object; span=(0, 8), match='Yinzheng'>
    '+' 的用法展示

    5>.'*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb''ab''a']

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("Y*","Yinzhengjie"))
     8 print(re.search("jie*","Yinzhengjie"))
     9 print(re.search("e*","Yinzhengjie"))
    10 
    11 
    12 #以上代码执行结果如下:
    13 <_sre.SRE_Match object; span=(0, 1), match='Y'>
    14 <_sre.SRE_Match object; span=(8, 11), match='jie'>
    15 <_sre.SRE_Match object; span=(0, 0), match=''>
    '*'用法展示

    6>.'?'     匹配前一个字符1次或0

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("Y?","Yinzhengjie"))
     8 print(re.search("jie?","Yinzhengjie"))
     9 print(re.search("e?","Yinzhengjieee"))
    10 
    11 
    12 #以上代码执行结果如下:
    13 <_sre.SRE_Match object; span=(0, 1), match='Y'>
    14 <_sre.SRE_Match object; span=(8, 11), match='jie'>
    15 <_sre.SRE_Match object; span=(0, 0), match=''>
    '?'用法展示

     7>.'{m}'   匹配前一个字符m次

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("jie{1}","Yinzhengjiejie"))
     8 print(re.search("(jie){2}","Yinzhengjiejie"))
     9 print(re.search("e{3}","Yinzhengjieee"))
    10 
    11 #以上代码执行结果如下:
    12 <_sre.SRE_Match object; span=(8, 11), match='jie'>
    13 <_sre.SRE_Match object; span=(8, 14), match='jiejie'>
    14 <_sre.SRE_Match object; span=(10, 13), match='eee'>
    '{m}' 用法展示

    8>.'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb''ab''abb']

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("e{1,3}","Yinzhengjieee"))
     8 print(re.search("e{2,3}","Yinzhengjieee"))
     9 print(re.search("e{3,10}","Yinzhengjieee"))
    10 
    11 
    12 #以上代码执行结果如下:
    13 <_sre.SRE_Match object; span=(5, 6), match='e'>
    14 <_sre.SRE_Match object; span=(10, 13), match='eee'>
    15 <_sre.SRE_Match object; span=(10, 13), match='eee'>
    '{n,m}'用法展示

    9>.'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("e|E","YinzhengjiE"))
     8 print(re.search("e|E","YinzhEngjie"))
     9 
    10 #以上代码执行结果如下:
    11 <_sre.SRE_Match object; span=(5, 6), match='e'>
    12 <_sre.SRE_Match object; span=(5, 6), match='E'>
    '|' 用法展示

    10>.'(...)' 分组匹配,re.search("(abc){2}a(123|456)c""abcabca456c").group() 结果 abcabca456c

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("d","612401199607237057")) #匹配一个数字
     8 print(re.search("d+","612401199607237057"))  #匹配数字一次或者多次,一般是贪婪匹配,会尽量把匹配最长的数字给你打印出来
     9 print(re.search("d...","612401199607237057")) #匹配一个数字和3个任意字符
    10 print(re.search("d{4}","612401199607237057"))  #匹配4个数字
    11 print(re.search("[0-9]{4}","612401199607237057")) #[0-9]其实就是等效于d
    12 print(re.search("(d{3})(d{3})(d...(3))","612401199607237057"))  #这个有点绕,我当时弄了好久才研究明白,给大家分享一下如何去看,前2个“(d{3})”表示匹配三个数字类型的字符,也就是要匹配6个数字,“(d...(3))”这个的意思是:匹配一个数字和三个任意字符,而且最后结尾标识符必须是数字“3”。
    13 print(re.search("(d{3})(d{3})(d(7))","612401199607237057")) #表示匹配以数字“7”结尾前面加七个数字[(d{3})(d{3})是6个数字后面还有个d所以总共是7个数字,后面的(3)我们可以理解是以“3”结尾即可。如果你看懂我上面的例子下面这个就不是事情啦!]
    14 print(re.search("(d{3})(d{3})(d...(3))","612401199607237057").group()) #取到值的结果
    15 print(re.search("(d{3})(d{3})(d...(3))","612401199607237057").groups())  #将取到的结果进行分组,这样大家就能看明白上面我举的那个例子啦
    16 number = re.search("(d{3})(d{3})(d...(3))","612401199607237057").groups()  #我们也可以将分组的信息赋值给一个变量,便于取值,如下:
    17 print(number[0])
    18 print(number[3])
    19 
    20 
    21 #以上代码执行结果如下:
    22 <_sre.SRE_Match object; span=(0, 1), match='6'>
    23 <_sre.SRE_Match object; span=(0, 18), match='612401199607237057'>
    24 <_sre.SRE_Match object; span=(0, 4), match='6124'>
    25 <_sre.SRE_Match object; span=(0, 4), match='6124'>
    26 <_sre.SRE_Match object; span=(0, 4), match='6124'>
    27 <_sre.SRE_Match object; span=(3, 14), match='40119960723'>
    28 <_sre.SRE_Match object; span=(4, 12), match='01199607'>
    29 40119960723
    30 ('401', '199', '60723', '3')
    31 401
    32 3
    '(...)' 分组匹配案例展示

     11>.'d','D','w','W' 用法:

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("D","!Yinzhengjie612401199607237057jie!!!!")) #匹配一个非数字
     8 print(re.search("D+","Yinzhengjie612401199607237057jie!!!!"))  #匹配多个非数字,
     9 print(re.search("D+d+","Yinzhengjie612401199607237057jie!!!!")) #匹配非数字和数字(注意,不会匹配到“jie!!!!”,因为它不是数字)
    10 print(re.search("D+d+D+","Yinzhengjie612401199607237057jie!!!!")) #都会被匹配到哟
    11 print(re.search("w+","Yinzhengjie612401199607237057jie!!!!")) #匹配[A-Za-z0-9]
    12 print(re.search("W+","Yinzhengjie612401199607237057jie!!!!"))  #匹配非字母大小写和数字,即不匹配[A-Za-z0-9],用于匹配特殊字符
    13 
    14 
    15 #以上代码执行结果如下:
    16 <_sre.SRE_Match object; span=(0, 1), match=''>
    17 <_sre.SRE_Match object; span=(0, 11), match='Yinzhengjie'>
    18 <_sre.SRE_Match object; span=(0, 29), match='Yinzhengjie612401199607237057'>
    19 <_sre.SRE_Match object; span=(0, 36), match='Yinzhengjie612401199607237057jie!!!!'>
    20 <_sre.SRE_Match object; span=(0, 32), match='Yinzhengjie612401199607237057jie'>
    21 <_sre.SRE_Match object; span=(32, 36), match='!!!!'>
    用法展示

    12>.'s' 与'(?P<name>...)' 分组匹配用法:

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("s+","!Yinzhengjie612401199607237057    !!!!"))        #可以匹配空格
     8 print(re.search("s+","!Yinzhengjie612401199607237057   	 !!!!"))      #可以匹配	
     9 print(re.search("s+","!Yinzhengjie612401199607237057   
     !!!!"))      #可以匹配
    
    10 print(re.search("s+","!Yinzhengjie612401199607237057   
     !!!!"))      #可以匹配
    
    11 print(re.search("s+","!Yinzhengjie612401199607237057   
     !!!!"))    #可以匹配
    
    12 print(re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","612401199907237057").groupdict() ) #这个看起来很复杂,其实挺简单的,这个比'(...)'分组匹配[是将结果放入一个tuple中]要简单的多,而咱们这个是将其变成一个字典,我们先看第一部分(?P<province>[0-9]{4}),就是让“province”为key,让“[0-9]{4}”为value,后面2个(?P<city>[0-9]{2})与(?P<birthday>[0-9]{4})也是一样的道理
    13 a = re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","612401199907237057").groupdict()  #同意,我们分组后可以对其进行取值
    14 print(a.get("birthday"))
    15 print(a.get("province"))
    '(?P...)' 分组匹配详解

     13>.findall的用法:

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.findall("[a-z]","Yinzhengjie612401199607237057jie!!!!
    6666
    @@@	")) #只匹配小写字母并将结果返回为一个列表
     8 print(re.findall("[A-z]","Yinzhengjie612401199607237057jie!!!!
    6666
    @@@	"))  #只匹配大写和小写的字母
     9 print(re.findall("[0-9]","Yinzhengjie612401199607237057jie!!!!
    6666
    @@@	"))  #只匹配数字
    10 print(re.findall("w","Yinzhengjie612401199607237057jie!!!!
    6666
    @@@	"))  #只匹配数字和字母
    11 print(re.findall("W","Yinzhengjie612401199607237057jie!!!!
    6666
    @@@	"))  #只匹配特殊字符
    12 
    13 
    14 
    15 #以上代码执行结果如下:
    16 ['i', 'n', 'z', 'h', 'e', 'n', 'g', 'j', 'i', 'e', 'j', 'i', 'e']
    17 ['Y', 'i', 'n', 'z', 'h', 'e', 'n', 'g', 'j', 'i', 'e', 'j', 'i', 'e']
    18 ['6', '1', '2', '4', '0', '1', '1', '9', '9', '6', '0', '7', '2', '3', '7', '0', '5', '7', '6', '6', '6', '6']
    19 ['Y', 'i', 'n', 'z', 'h', 'e', 'n', 'g', 'j', 'i', 'e', '6', '1', '2', '4', '0', '1', '1', '9', '9', '6', '0', '7', '2', '3', '7', '0', '5', '7', 'j', 'i', 'e', '6', '6', '6', '6']
    20 ['!', '!', '!', '!', '
    ', '
    ', '@', '@', '@', '	']
    re.findall用法展示

    14>.split用法

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.split("W","172.30.1.2")) #取以特殊字符为分隔符取值
     8 print(re.split("W","192.168@2!24")) #同上
     9 
    10 
    11 
    12 #以上代码执行结果如下:
    13 ['172', '30', '1', '2']
    14 ['192', '168', '2', '24']
    re.split用法展示

    15>.sub用法:

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.sub("d{4}","2017","I was born in 1991-05-19,alex was born in 1937-9-15",count=1)) #表示对"I was born in 1991-05-19"这个字符串进行匹配"d{4}"前4个数字,然后将匹配的到的数据用"2017"去替换掉,注意:count=1表示只匹配1次,如果不指定的话会默认匹配所有的连续的数字哟!
     8 print(re.sub("d{4}","2017","I was born in 1991-05-19,alex was born in 1937-9-15",count=2)) #默认匹配2次
     9 print(re.sub("d{4}","2017","I was born in 1991-05-19,alex was born in 1937-9-15",))  #默认全部匹配
    10 
    11 
    12 #以上代码执行结果如下:
    13 I was born in 2017-05-19,alex was born in 1937-9-15
    14 I was born in 2017-05-19,alex was born in 2017-9-15
    15 I was born in 2017-05-19,alex was born in 2017-9-15
    re.sub用法展示

     16>.反斜杠的困扰

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 '''
     8         与大多数编程语言相同,正则表达式里使用""作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\"表示。同样,匹配一个数字的"\d"可以写成r"d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
     9 '''
    10 
    11 print(re.search("\d","database"))   #表示匹配数字
    12 print(re.search(r"\d","database"))  #表示匹配字母“d”(可以把一些特殊的符号匹配出来如:”D“,”“等等),法一
    13 print(re.search("\\d","database")) #表示匹配字母“d”,法二
    14 
    15 
    16 
    17 #以上代码执行结果如下:
    18 None
    19 <_sre.SRE_Match object; span=(0, 2), match='\d'>
    20 <_sre.SRE_Match object; span=(0, 2), match='\d'>
    特殊字母如何转义成为普通字符

    17>.仅需了解几个匹配模式

     1 #!/usr/bin/env python
     2 #_*_coding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/
     5 #EMAIL:y1053419035@qq.com
     6 import re
     7 print(re.search("[a-z]{2}","My Name Is Yinzhengjie",flags=re.I)) #忽略大小写
     8 print(re.search(".+","My Name Is
     Yinzhengjie",flags=re.S))  #点任意匹配模式,改变'.'的行为,可以匹配"
    ","
    ","
    "等等。
     9 print(re.search("^M","
    My Name Is Yinzhengjie",flags=re.I))
    10 print(re.search("^M","
    My Name Is Yinzhengjie",flags=re.M))  #匹配以M开头,可以过滤掉换行符,用“flags=re.M”实现。
    11 
    12 
    13 #以上代码执行结果如下:
    14 <_sre.SRE_Match object; span=(0, 2), match='My'>
    15 <_sre.SRE_Match object; span=(0, 24), match='My Name Is
     Yinzhengjie'>
    16 None
    17 <_sre.SRE_Match object; span=(1, 2), match='M'>
    扩充Tips
  • 相关阅读:
    jQuery ajax传多个参数
    PHP 上传图片和安全处理
    PHP CI框架email类发送邮件
    2016-4-7
    jquery 轮播图
    CI控制器的继承问题
    2016-4-1
    2016-3-31 总结
    php内置函数call_user_func()
    discuz-目录
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/6428006.html
Copyright © 2020-2023  润新知