zoukankan      html  css  js  c++  java
  • 常用模块

    1. time模块

    1.1 时间的格式

    1) 时间戳(timestamp):

    ​ 从1970年到现在经过的秒数

    作用:

    ​ 用于时间间隔的计算

    print(time.time())#1585550344.012155
    

    2) 按照某种格式显示的时间(format string):

    作用 : 展示时间 2020-03-30 11:11:11

    print(time.strftime('%Y-%m-%d %H:%M:%S %p'))
    print(time.strftime('%Y-%m-%d %X'))
    print(time.strftime('%Y-%m-%d %H %p'))
    
    #2020-03-30 14:39:04 PM
    #2020-03-30 14:39:04
    #2020-03-30 14 PM
    
    

    3) 结构化的时间(struct_time):

    作用 : 用于单独获取时间的某一部分

    res = time.localtime()
    print(res)  
    # time.struct_time(tm_year=2020, tm_mon=3, tm_mday=30, tm_hour=14, tm_min=41, tm_sec=27, tm_wday=0, tm_yday=90, tm_isdst=0)
    print(res.tm_year)  	# 年:2020
    print(res.tm_yday)  	# 今年的第90天
    print(res.tm_hour)  	# 时:14
    print(res.tm_min)  		# 分:41
    print(res.tm_sec)  		# 秒:27
    print(res.tm_mday)  	# 这个月的第30天
    print(res.tm_mon)  		# 月:3
    print(res.tm_wday)  	# 星期(0-6):0(星期一)
    print(res.tm_zone)  	# 当前的时间区域
    

    2. datetime模块

    print(datetime.datetime.now())
    print(datetime.datetime.now() + datetime.timedelta(days=3))
    #计算3天后的时间
    print(datetime.datetime.now() + datetime.timedelta(weeks=1))
    #计算7天后的时间
    

    3. 时间模块需要掌握的操作

    3.1 时间格式的转换

    struct_time->时间戳

    import time
    s_time=time.localtime()
    print(s_time)
    print(time.mktime(s_time))
    

    时间戳->struct_time

    tp_time=time.time()
    print(time.localtime(tp_time))
    

    世界标准时间与本地时间

    print(time.localtime())# 上海时区(东八区)
    print(time.gmtime()) # 世界标准时间,了解
    print(time.localtime(333333333))
    print(time.gmtime(333333333))
    

    struct_time->格式化的字符串形式的时间

    s_time=time.localtime()
    print(time.strftime('%Y-%m-%d %H:%M:%S',s_time))
    #2020-03-30 14:58:30
    print(time.strftime('%Y-%m-%d %H:%M:%S'))
    #2020-03-30 14:58:30
    print(time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S'))
    #time.struct_time(tm_year=1988, tm_mon=3, tm_mday=3, tm_hour=11, tm_min=11, tm_sec=11, tm_wday=3, tm_yday=63, tm_isdst=-1)
    

    3.2 format string<------>timestamp

    '1988-03-03 11:11:11'+7
    # format string--->struct_time--->timestamp
    struct_time=time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S')
    timestamp=time.mktime(struct_time)+7*86400
    print(timestamp)#573966671.0
    
    # format string<---struct_time<---timestamp
    res=time.strftime('%Y-%m-%d %X',time.localtime(timestamp))
    print(res)#1988-03-10 11:11:11
    

    了解知识:

    import time
    print(time.asctime())# Mon Mar 30 15:03:54 常用于Linux操作系统
    
    import datetime
    print(datetime.datetime.now())
    print(datetime.datetime.fromtimestamp(333333))
    # 时间戳直接转成日期格式 1970-01-05 04:35:33
    

    4. random模块

    4.1 常用命令

    import random
    
    print(random.random())
    #(0,1)----float    大于0且小于1之间的小数
    print(random.randint(1, 3)) 
    # [1,3]    大于等于1且小于等于3之间的整数
    
    print(random.randrange(1, 3)) 
    # [1,3)    大于等于1且小于3之间的整数
    
    print(random.choice([111, 'aaa', [4, 5]])) 
    # 1或者23或者[4,5]
    
    print(random.sample([111, 'aaa', 'ccc','ddd'],2))#任意2个组合
    print(random.sample([111, 'aaa', 'ccc','ddd'],3))#任意三个组合
    
    print(random.uniform(1, 3)) 
    # 大于1小于3的小数,如1.927109612082716
    
    item = [1, 3, 5, 7, 9]
    random.shuffle(item)  # 打乱item的顺序,相当于"洗牌"
    print(item)
    

    4.2 应用案例:随机验证码

    import random
    #随机生成4位大写字母+数字的验证码
    def make_code(size=4):
        res=''
        for i in range(size):
            s1=chr(random.randint(65,90))#从26大写字母中随机取出一个
            s2=str(random.randint(0,9))#从10个数字中随机取出一个
            res+=random.choice([s1,s2])#随机取出一个,加到res中
        return res
    print(make_code(6))
    
    ps:
        小写字母则加入:s2 = chr(random.randint(97,122))
    

    5. os模块

    5.1 常用命令

    os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
    os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
    os.curdir  返回当前目录: ('.')
    os.pardir  获取当前目录的父目录字符串名:('..')
    os.makedirs('dirname1/dirname2')    可生成多层递归目录
    os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
    os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
    os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    os.remove()  删除一个文件
    os.rename("oldname","newname")  重命名文件/目录
    os.stat('path/filename')  获取文件/目录信息
    os.sep    输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
    os.linesep    输出当前平台使用的行终止符,win下为"	
    ",Linux下为"
    "
    os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
    os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
    os.system("bash command")  运行shell命令,直接显示
    os.environ  获取系统环境变量
    os.path.abspath(path)  返回path规范化的绝对路径
    os.path.split(path)  将path分割成目录和文件名二元组返回
    os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
    os.path.basename(path)  返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素
    os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
    os.path.isabs(path)  如果path是绝对路径,返回True
    os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
    os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
    os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
    os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
    os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
    os.path.getsize(path) 返回path的大小
    

    5.2 常用命令解析

    os.listdir() 获取某一个文件夹下的子文件和文件名

    # 获取某一个文件夹下所有的子文件以及子文件夹的名字
    res=os.listdir('../../week4')
    ['day16', 'day17', 'day18', 'day19', 'day20']
    res=os.listdir('.')
    #['01 时间模块.py', '02 random模块.py', '03 os模块.py', '04 sys模块.py', 'day21 笔记.md', 'run.py', '作业(3).txt', '笔记.txt']
    print(res)
    

    os.path.getsize() 查看文件大小

    size=os.path.getsize(r'作业(3).txt')#218
    print(size)
    
    os.remove()  #删除一个文件
    os.rename("作业(3).txt","作业.txt")  #重命名文件/目录
    
    print(os.listdir('.'))
    ['01 时间模块.py', '02 random模块.py', '03 os模块.py', '04 sys模块.py', 'day21 笔记.md', 'run.py', '作业.txt', '笔记.txt']
    

    os.environ 获取系统环境变量

    # 规定:key与value必须都为字符串
    
    os.environ['aaaaaaaaaa']='111'
    print(os.environ)
    

    文件相关操作

    print(__file__)
    #E:/python学习/week5/day21/03 os模块.py
    print(os.path.abspath(__file__)) #返回path规范化的绝对路径
    #E:老男孩python学习week5day213 os模块.py
    
    print(os.path.dirname(r'/a/b/c/d.txt'))#路径的文件夹
    print(os.path.basename(r'/a/b/c/d.txt'))#路径的文件名
    #/a/b/c
    #d.txt
    print(os.path.split('/a/b/c/d.txt'))        
    # 会把路径和文件切分开:('/a/b/c', 'd.txt')
    print(os.path.split(__file__))              
    # 会把路径和文件切分开:('E:/python学习/week5/day21', '03 os模块.py')
    
    print(os.path.isabs(r'../week5'))    # 判断是否为绝对路径
    
    print(os.path.isfile(r'笔记.txt'))
    print(os.path.isfile(r'aaa'))
    print(os.path.isdir(r'aaa'))
    #True
    #False
    #True
    print(os.path.join('a','s','b','c','d'))#文件拼接
    print(os.path.join('a','/','b','c','d'))
    print(os.path.join('a','C:','b','c','d'))
    #ascd
    #/bcd
    #C:bcd
    
    

    规定起始目录

    # 推荐用这种
    BASE_DIR=os.path.dirname(os.path.dirname(__file__))
    print(BASE_DIR)
    # 不推荐用这种
    BASE_DIR=os.path.normpath(os.path.join(
        __file__,
        '..',
        '..'
    ))
    print(BASE_DIR)
    # 在python3.5之后,推出了一个新的模块pathlib  
    #模块功能清晰,但版本太新,不推荐
    from pathlib import Path
    
    res = Path(__file__).parent.parent
    print(res)
    res=Path('/a/b/c') / 'd/e.txt'
    print(res)#acde.txt
    
    print(res.resolve())# 格式规范化,把 / 变成 :E:acde.txt
    
    

    6. sys模块

    6.1 常用命令

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

    6.2 常用命令解析

    sys.argv 命令行参数List,第一个元素是程序本身路径

    # python3.8 run.py 1 2 3
    # sys.argv在Python解释器内,接受外界传来的值,获取的是解释器后参数值
    print(sys.argv)
    #['E:/python学习/week5/day21/run.py','1','2','3']
    
    

    文件拷贝的原始方法

    src_file = input('原文件路径:').strip()
    dst_file = input('新文件路径:').strip()
    
    with open(r'%s'%src_file, mode='rb') as read_f,
        open(r'%s'%dst_file, mode='wb') as write_f:
        for line in read_f:
            write_f.write(line)
    
    

    文件拷贝的新方法

    src_file = sys.argv[1]
    dst_file = sys.argv[2]
    ['E:/python学习/week5/day21/run.py','a.txt','b.txt']
    with open(r'%s'%src_file, mode='rb') as read_f,
        open(r'%s'%dst_file, mode='wb') as write_f:
        for line in read_f:
            write_f.write(line)
    # 在run.py所在的文件夹下,按住shift,右键,选择“在此处打开power shell”,输入
    # 格式:python3 run.py 原文件路径 新文件路径
    # python3 run.py D:1.docx D:2.docx   #拷贝成功
    
    

    6.3 应用:进度条

    #基础知识
    # print('[%-50s]' %'#')
    # print('[%-50s]' % '##')
    # print('[%-50s]' % '###')
    
    # 输出:
    [#                                                 ]
    [##                                                ]
    [###                                               ]
    import time
    #进度条显示
    res = ''
    for i in range(50):
        res += '#'
        time.sleep(0.2)
        print('
     [%-50s]' % res, end='')
        
    # 输出:  [##################################################]
        
    #进阶
    import time
    recv_size = 0
    total_size = 25600
    
    while recv_size < total_size:
        # 模拟网速
        time.sleep(0.2)
        # 下载了1024个字节的数据
        recv_size += 1024
        # 打印进度条
        # print(recv_size)
        percent = recv_size / total_size    # 1024 / 25600
        if percent > 1:
            percent = 1
        res = int(50 * percent) * '>'
        print('
     [%-50s] %d%%' % (res,percent*100), end='')
        
    #函数最终版
    import time
    
    def progress(percent):
        if percent > 1:
            percent = 1
        res = int(50 * percent) * '>'
        print('
     [%-50s] %d%%' % (res,percent*100), end='')
    
    recv_size = 0
    total_size = 25600
    
    while recv_size < total_size:
        time.sleep(0.2)
        recv_size += 1024
        percent = recv_size / total_size    # 1024 / 25600
        progress(percent)
    
    

    7. shutil模块

    ​ 高级的 文件、文件夹、压缩包 处理模块

    7.1 基本使用

    import shutil
    shutil.copyfile( src, dst)   #从源src复制到dst中去。 如果当前的dst已存在的话就会被覆盖掉
    
    shutil.move( src, dst)  #移动文件或重命名
    
    shutil.copymode( src, dst) #只是会复制其权限其他的东西是不会被复制的
    
    shutil.copystat( src, dst) #复制权限、最后访问时间、最后修改时间
    
    shutil.copy( src, dst)  #复制一个文件到一个文件或一个目录
    
    shutil.copy2( src, dst)  #在copy上的基础上再复制文件最后访问时间与修改时间也复制过来了,类似于cp –p的东西
    
    shutil.copy2( src, dst)  #如果两个位置的文件系统是一样的话相当于是rename操作,只是改名;如果是不在相同的文件系统的话就是做move操作
    
    shutil.copytree( olddir, newdir, True/Flase) #把olddir拷贝一份newdir,如果第3个参数是True,则复制目录时将保持文件夹下的符号连接,如果第3个参数是False,则将在复制的目录下生成物理副本来替代符号连接
    
    shutil.rmtree( src )   #递归删除一个目录以及目录内的所有内容
    
    

    7.2 高级使用

    shutil.copyfileobj(fsrc, fdst[, length])
    将文件内容拷贝到另一个文件中

    shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
    
    

    shutil.copyfile(src, dst)拷贝文件

    shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
    
    

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

    shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
    
    

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

    shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
    
    

    shutil.copy(src, dst) 拷贝文件和权限

    shutil.copy('f1.log', 'f2.log')
    
    

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

    shutil.copy2('f1.log', 'f2.log')
    
    

    shutil.ignore_patterns(*patterns)
    shutil.copytree(src, dst, symlinks=False, ignore=None)
    递归的去拷贝文件夹

    shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) 
    #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除 
    
    
    shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    
    '''
    通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件
    '''
    
    

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

    shutil.rmtree('folder1')
    
    

    shutil.move(src, dst) 递归的去移动文件,它类似mv命令,其实就是重命名。

    shutil.move('folder1', 'folder3')
    
    

    shutil.make_archive(base_name, format,...)

    创建压缩包并返回文件路径,例如:zip、tar

    创建压缩包并返回文件路径,例如:zip、tar

    base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    如 data_bak                       =>保存至当前路径
    如:/tmp/data_bak =>保存至/tmp/
    format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    root_dir: 要压缩的文件夹路径(默认当前目录)
    owner: 用户,默认当前用户
    group: 组,默认当前组
    logger: 用于记录日志,通常是logging.Logger对象
    
    
    #将 /data 下的文件打包放置当前程序目录
    import shutil
    ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
      
      
    #将 /data下的文件打包放置 /tmp/目录
    import shutil
    ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
    
    

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

    import zipfile
    
    # 压缩
    z = zipfile.ZipFile('laxi.zip', 'w')
    z.write('a.log')
    z.write('data.data')
    z.close()
    
    # 解压
    z = zipfile.ZipFile('laxi.zip', 'r')
    z.extractall(path='.')
    z.close()
    
    zipfile压缩解压缩
    
    
    import tarfile
    
    # 压缩
    >>> t=tarfile.open('/tmp/egon.tar','w')
    >>> t.add('/test1/a.py',arcname='a.bak')
    >>> t.add('/test1/b.py',arcname='b.bak')
    >>> t.close()
    
    
    # 解压
    >>> t=tarfile.open('/tmp/egon.tar','r')
    >>> t.extractall('/egon')
    >>> t.close()
    
    tarfile压缩解压缩
    
    

    8. json和pickle模块

    8.1 什么是序列化和反序列化

    内存中的数据类型---->序列化---->特定的格式(json格式或者pickle格式)
    内存中的数据类型<----反序列化<----特定的格式(json格式或者pickle格式)

    土办法:

     {'aaa':111}--->序列化str({'aaa':111})----->"{'aaa':111}"
     {'aaa':111}<---反序列化eval("{'aaa':111}")<-----"{'aaa':111}"
    

    8.2 为何要序列化

    序列化得到结果=>特定的格式的内容有两种用途
    1、可用于存储=》用于存档
    2、传输给其他平台使用=》跨平台数据交互
    python java
    列表 特定的格式 数组

    强调:
    针对用途1=》:可是一种专用的格式=》pickle只有python可以识别
    针对用途2=》:应该是一种通用、能够被所有语言识别的格式=》json

    8.3 如何序列化和反序列化

    示范1

    import json
    # 序列化
    json_res=json.dumps([1,'aaa',True,False])
    # print(json_res,type(json_res)) # "[1, "aaa", true, false]"
    
    # 反序列化
    l=json.loads(json_res)
    print(l,type(l))
    

    示范2

    # 序列化的结果写入文件的复杂方法
    json_res=json.dumps([1,'aaa',True,False])
    with open('test.json',mode='wt',encoding='utf-8') as f:
        f.write(json_res)
    
    # 将序列化的结果写入文件的简单方法
    with open('test.json',mode='wt',encoding='utf-8') as f:
        json.dump([1,'aaa',True,False],f)
    
    
    # 从文件读取json格式的字符串进行反序列化操作的复杂方法
    with open('test.json',mode='rt',encoding='utf-8') as f:
        json_res=f.read()
        l=json.loads(json_res)
        print(l,type(l))
    
    # 从文件读取json格式的字符串进行反序列化操作的简单方法
    with open('test.json',mode='rt',encoding='utf-8') as f:
        l=json.load(f)
        print(l,type(l))
    
    

    8.4 json强调

    json格式兼容的是所有语言通用的数据类型,不能识别某一语言的所独有的类型

    一定要搞清楚json格式,不要与python混淆

    json.dumps({1,2,3,4,5})#json中没有Python集合的概念
    # 无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
    l=json.loads('[1, "aaa", true, false]')
    l=json.loads("[1,1.3,true,'aaa', true, false]")
    print(l[0])
    

    8.5 json了解知识

    #在python解释器2.7与3.6之后都可以json.loads(bytes类型),但唯独3.5不可以
    l = json.loads(b'[1, "aaa", true, false]')
    print(l, type(l))
    
    with open('test.json',mode='rb') as f:
        l=json.load(f)
    
    
    res=json.dumps({'name':'哈哈哈'})
    print(res,type(res))
    
    res=json.loads('{"name": "u54c8u54c8u54c8"}')
    print(res,type(res))
    

    8.6 猴子补丁和ujson

    什么是猴子补丁?

    ​ 猴子补丁的核心就是用自己的代码替换所用模块的源代码

    猴子补丁的功能(一切皆对象)

      拥有在模块运行时替换的功能, 例如: 一个函数对象赋值给另外一个函数对象(把函数原本的执行的功能给替换了)

    猴子补丁的应用

    #json 在dumps和loads的运行速度不如ujson,可以在程序入口处将两个方法替换为ujson中的dumps和loads方法
    #在入口处打猴子补丁,即run.py
    import json
    import ujson
    
    def monkey_patch_json():
        json.__name__ = 'ujson'
        json.dumps = ujson.dumps
        json.loads = ujson.loads
    
    monkey_patch_json() # 在入口文件出运行
    
    #import ujson as json # 不行,只需要替换两个方法,而不是全部替换
    
    # 后续代码中的应用,使用不发生改变
    json.dumps()
    json.dumps()
    json.loads()
    json.loads()
    

    8.7 pickle模块

    import pickle
    res=pickle.dumps({1,2,3,4,5})
    print(res,type(res))
    
    s=pickle.loads(res)
    print(s,type(s))
    

    9. xml和shelve模块(了解)

    9.1 shelve模块

    shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;

    key必须为字符串,而值可以是python所支持的数据类型

    import shelve
    
    f=shelve.open(r'sheve.txt')
    # f['stu1_info']={'name':'egon','age':18,'hobby':['piao','smoking','drinking']}
    # f['stu2_info']={'name':'gangdan','age':53}
    # f['school_info']={'website':'http://www.pypy.org','city':'beijing'}
    
    print(f['stu1_info']['hobby'])
    f.close()
    

    9.2 xml模块

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

    xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:

    # print(root.iter('year')) #全文搜索
    # print(root.find('country')) #在root的子节点找,只找一个
    # print(root.findall('country')) #在root的子节点找,找所有
    
    import xml.etree.ElementTree as ET
     
    tree = ET.parse("xmltest.xml")
    root = tree.getroot()
    print(root.tag)
     
    #遍历xml文档
    for child in root:
        print('========>',child.tag,child.attrib,child.attrib['name'])
        for i in child:
            print(i.tag,i.attrib,i.text)
     
    #只遍历year 节点
    for node in root.iter('year'):
        print(node.tag,node.text)
    #---------------------------------------
    
    import xml.etree.ElementTree as ET
     
    tree = ET.parse("xmltest.xml")
    root = tree.getroot()
     
    #修改
    for node in root.iter('year'):
        new_year=int(node.text)+1
        node.text=str(new_year)
        node.set('updated','yes')
        node.set('version','1.0')
    tree.write('test.xml')
     
     
    #删除node
    for country in root.findall('country'):
       rank = int(country.find('rank').text)
       if rank > 50:
         root.remove(country)
     
    tree.write('output.xml')
    
    #在country内添加(append)节点year2
    import xml.etree.ElementTree as ET
    tree = ET.parse("a.xml")
    root=tree.getroot()
    for country in root.findall('country'):
        for year in country.findall('year'):
            if int(year.text) > 2000:
                year2=ET.Element('year2')
                year2.text='新年'
                year2.attrib={'update':'yes'}
                country.append(year2) #往country节点下添加子节点
    
    tree.write('a.xml.swap')
    

    10. configparser模块

    用于读取某些特定格式的配置文件(例如:ini,cft结尾的)

    #配置文件如下:
    # 注释1: 注释2
    
    [section1]
    k1 = v1
    k2:v2
    user=egon
    age=18
    is_admin=true
    salary=31
    [section2]
    k1 = v1
    
    import configparser
    #将配置文件加载到内存
    config=configparser.ConfigParser()
    config.read('test.ini')
    
    # 1、获取sections
    print(config.sections())
    #['section1', 'section2']
    
    # 2、获取某一section下的所有options
    print(config.options('section1'))
    #['k1', 'k2', 'user', 'age', 'is_admin', 'salary']
    
    # 3、获取items
    print(config.items('section1'))
    # [('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]
    
    # 4、获取指定配置信息
    res=config.get('section1','user')
    print(res,type(res))
    
    res=config.getint('section1','age')
    print(res,type(res))
    
    res=config.getboolean('section1','is_admin')
    print(res,type(res))
    
    res=config.getfloat('section1','salary')
    print(res,type(res))
    

    11. hashlib模块

    1 什么是哈希hash

    hash一类算法,该算法接受传入的内容,经过运算得到一串hash值

    hash值的特点:

    • I 只要传入的内容一样,得到的hash值必然一样
    • II 不能由hash值返解成内容
    • III 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是一定

    2 hash的用途

    用途1:特点II用于密码密文传输与验证
    用途2:特点I、III用于文件完整性校验

    3 如何用

    hash算法就像一座工厂,工厂接收你送来的原材料(可以用m.update()为工厂运送原材料),经过加工返回的产品就是hash值

    import hashlib
    
    m=hashlib.md5()
    m.update('hello'.encode('utf-8'))
    m.update('world'.encode('utf-8'))
    res=m.hexdigest() # 'helloworld'
    print(res)
    
    m1=hashlib.md5('he'.encode('utf-8'))
    m1.update('llo'.encode('utf-8'))
    m1.update('w'.encode('utf-8'))
    m1.update('orld'.encode('utf-8'))
    res=m1.hexdigest()# 'helloworld'
    print(res)
    '''
    注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样
    但是update多次为校验大文件提供了可能。
    '''
    

    4 应用

    示例1:模拟撞库

    #alex3714的m5哈希值
    cryptograph='aee949757a2e698417463d47acac93df'
    import hashlib
    
    # 制作密码字段
    passwds=[
        'alex3714',
        'alex1313',
        'alex94139413',
        'alex123456',
        '123456alex',
        'a123lex',
    ]
    
    dic={}
    for p in passwds:
        res=hashlib.md5(p.encode('utf-8'))
        dic[p]=res.hexdigest()
    
    # 模拟撞库得到密码
    for k,v in dic.items():
        if v == cryptograph:
            print('撞库成功,明文密码是:%s' %k)
            break
    

    示例2:提升撞库的成本=>密码加盐(对密码添加额外字段)

    import hashlib
    
    m=hashlib.md5()
    
    m.update('天王'.encode('utf-8'))
    m.update('alex3714'.encode('utf-8'))
    m.update('盖地虎'.encode('utf-8'))
    print(m.hexdigest())
    
    #对于一个很大的文件,并不是将全部内容进行加密
    #而是选取文件的几个部分组成的数据,进行加密,
    #这样能很好的提升文件校验效率
    #m.update(文件所有的内容)
    #m.hexdigest()
    
    f=open('a.txt',mode='rb')
    f.seek()
    f.read(2000) # 巨琳
    m1.update(文见的一行)
    
    m1.hexdigest()
    

    12. subprocess模块

    subprocess模块,主要执行子进程,用于执行系统命令的模块

    注意:其返回值的编码类型,与所使用的操作系统有关,

    windows -》gbk, mac-》utf-8

    import subprocess
    
    obj=subprocess.Popen('echo 123 ; ls / ; ls /root',shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE,
                     )
    # print(obj)
    # res=obj.stdout.read()
    # print(res.decode('utf-8'))
    
    err_res=obj.stderr.read()
    print(err_res.decode('utf-8'))
    
    

    13. logging模块

    1 日志级别和基本配置

    import logging
    
    # 一:日志配置
    logging.basicConfig(
        # 1、日志输出位置:1、终端 2、文件
        # filename='access.log', # 不指定,默认打印到终端
    
        # 2、日志格式
        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    
        # 3、时间格式
        datefmt='%Y-%m-%d %H:%M:%S %p',
    
        # 4、日志级别
        # critical => 50
        # error => 40
        # warning => 30
        # info => 20
        # debug => 10
        level=30,
    )
    
    # 二:输出日志
    logging.debug('调试debug')
    logging.info('消息info')
    logging.warning('警告warn')
    logging.error('错误error')
    logging.critical('严重critical')
    
    '''
    # 注意下面的root是默认的日志名字
    WARNING:root:警告warn
    ERROR:root:错误error
    CRITICAL:root:严重critical
    '''
    

    2 日志配置字典

    """
    日志配置字典LOGGING_DIC
    """
    # 1、定义三种日志输出格式,日志中可能用到的格式化串如下
    # %(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用户输出的消息
    
    # 2、强调:其中的%(name)s为getlogger时指定的名字
    standard_format = '%(asctime)s - %(threadName)s:%(thread)d - 日志名字:%(name)s - %(filename)s:%(lineno)d -' 
                      '%(levelname)s - %(message)s'
    
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    
    test_format = '%(asctime)s] %(message)s'
    
    # 3、日志配置字典
    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        #  多个日志格式
        'formatters': {
        #定制的日志格式的名字
            'standard': {
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
            'test': {
                'format': test_format
            },
        },
        'filters': {},
        # handlers是日志的接收者,控制日志的输出位置,不同的handler会将日志输出到不同的位置
        'handlers': {
            #打印到终端的日志
            'console': {
                'level': 'DEBUG',#日志的级别,也可以写成数字
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                # 'maxBytes': 1024*1024*5,  # 日志大小 5M
                'maxBytes': 1000,
                'backupCount': 5,
                'filename': 'a1.log',  # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
                'encoding': 'utf-8',
                'formatter': 'standard',
    
            },
            #打印到文件的日志,收集info及以上的日志
            'other': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',  # 保存到文件
                'filename': 'a2.log', # os.path.join(os.path.dirname(os.path.dirname(__file__)),'log','a2.log')
                'encoding': 'utf-8',
                'formatter': 'test',
    
            },
        },
        # loggers是日志的产生者,产生不同级别的日志,产生的日志会传递给handler然后控制输出
        'loggers': {
            #logging.getLogger(__name__)拿到的logger配置
            'kkk': {
                'handlers': ['console','other'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
                'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
            },
            '终端提示': {
                'handlers': ['console',],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
                'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
            },
            #真对多种相同的输出,靠不同的日志名去区分功能的,可以填''
            '': {
                'handlers': ['default', ],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',  # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制)
                'propagate': False,  # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递
            },
        },
    }
    
    

    3 logging的使用

    import settings
    
    # !!!强调!!!
    # 1、logging是一个包,需要使用其下的config、getLogger,可以如下导入
    # from logging import config
    # from logging import getLogger
    
    # 也可以使用如下导入
    import logging.config # 这样连同logging.getLogger都一起导入了,然后使用前缀logging.config.
    
    # logging.config.dictConfig(settings.LOGGING_DIC)
    # print(logging.getLogger)
    
    # 接下来要做的是:拿到日志的产生者即loggers来产生日志
    # 第一个日志的产生者:kkk
    # 第二个日志的产生者:bbb
    
    # 但是需要先导入日志配置字典LOGGING_DIC
    import settings
    from logging import config,getLogger
    
    config.dictConfig(settings.LOGGING_DIC)
    
    
    # logger1=getLogger('kkk')
    # logger1.info('这是一条info日志')
    
    # logger2=getLogger('终端提示')
    # logger2.info('logger2产生的info日志')
    
    # logger3=getLogger('用户交易')
    # logger3.info('logger3产生的info日志')
    
    logger4=getLogger('用户常规')
    logger4.info('logger4产生的info日志')
    
    # 补充两个重要额知识
    # 1、日志名的命名
    #    日志名是区别日志业务归属的一种非常重要的标识
    
    # 2、日志轮转
    #    日志不能轻易的删除,不应该在一个文件里不断累加,
    #    定期的将文件中的内容剪切走,(设置阈值,超过多少M执行)
    #    日志记录着程序员运行过程中的关键信息
    

    14. re模块

    1 什么是正则?

     正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。****(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

    2 常用匹配模式(元字符)

    http://blog.csdn.net/yufenghyc/article/details/51078107

    # =================================匹配模式=================================
    #一对一的匹配
    # 'hello'.replace(old,new)
    # 'hello'.find('pattern')
    
    #正则匹配
    import re
    #w与W
    print(re.findall('w','hello egon 123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
    print(re.findall('W','hello egon 123')) #[' ', ' ']
    
    #s与S
    print(re.findall('s','hello  egon  123')) #[' ', ' ', ' ', ' ']
    print(re.findall('S','hello  egon  123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
    
    #
     	都是空,都可以被s匹配
    print(re.findall('s','hello 
     egon 	 123')) #[' ', '
    ', ' ', ' ', '	', ' ']
    
    #
    与	
    print(re.findall(r'
    ','hello egon 
    123')) #['
    ']
    print(re.findall(r'	','hello egon	123')) #['
    ']
    
    #d与D
    print(re.findall('d','hello egon 123')) #['1', '2', '3']
    print(re.findall('D','hello egon 123')) #['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' ']
    
    #A与
    print(re.findall('Ahe','hello egon 123')) #['he'],A==>^
    print(re.findall('123','hello egon 123')) #['he'],==>$
    
    #^与$
    print(re.findall('^h','hello egon 123')) #['h']
    print(re.findall('3$','hello egon 123')) #['3']
    
    # 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |
    #.:匹配除了
    之外任意一个字符,指定re.DOTALL之后才能匹配换行符
    print(re.findall('a.b','a1b')) #['a1b']
    print(re.findall('a.b','a1b a*b a b aaab')) #['a1b', 'a*b', 'a b', 'aab']
    print(re.findall('a.b','a
    b')) #[]
    print(re.findall('a.b','a
    b',re.S)) #['a
    b']
    print(re.findall('a.b','a
    b',re.DOTALL)) #['a
    b']同上一条意思一样
    
    #*:左侧字符重复0次或无穷次,性格贪婪
    print(re.findall('ab*','bbbbbbb')) #[]
    print(re.findall('ab*','a')) #['a']
    print(re.findall('ab*','abbbb')) #['abbbb']
    
    #?:左侧字符重复0次或1次,性格贪婪
    print(re.findall('ab?','a')) #['a']
    print(re.findall('ab?','abbb')) #['ab']
    #匹配所有包含小数在内的数字
    print(re.findall('d+.?d*',"asdfasdf123as1.13dfa12adsf1asdf3")) #['123', '1.13', '12', '1', '3']
    #+:左侧字符重复1次或无穷次,性格贪婪
    print(re.findall('ab+','a')) #[]
    print(re.findall('ab+','abbb')) #['abbb']
    
    #.*默认为贪婪匹配
    print(re.findall('a.*b','a1b22222222b')) #['a1b22222222b']
    
    #.*?为非贪婪匹配:推荐使用
    print(re.findall('a.*?b','a1b22222222b')) #['a1b']
    
    
    #{n,m}左侧字符重复n次到m次,性格贪婪
    # {0,} => *
    # {1,} => +
    # {0,1} => ?
    # {n}单独一个n代表只出现n次,多一次不行少一次也不行
    print(re.findall('ab{2}','abbb')) #['abb']
    print(re.findall('ab{2,4}','abbb')) #['abb']
    print(re.findall('ab{1,}','abbb')) #'ab{1,}' ===> 'ab+'
    print(re.findall('ab{0,}','abbb')) #'ab{0,}' ===> 'ab*'
    
    #[]匹配指定字符一个
    print(re.findall('a[1*-]b','a1b a*b a-b')) #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾
    print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']
    print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']
    print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #[]内的^代表的意思是取反,所以结果为['a=b']
    print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb')) #[]内的^代表的意思是取反,所以结果为['a=b']
    
    ## print(re.findall('a\c','ac')) #对于正则来说a\c确实可以匹配到ac,但是在python解释器读取a\c时,会发生转义,然后交给re去执行,所以抛出异常
    print(re.findall(r'a\c','ac')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义
    print(re.findall('a\\c','ac')) #同上面的意思一样,和上面的结果一样都是['a\c']
    
    # print(re.findall('adb','a1111111b a3b a4b a9b aXb a b a
    b',re.DOTALL))
    # print(re.findall('a[501234]b','a1111111b a3b a4b a9b aXb a b a
    b',re.DOTALL))
    # print(re.findall('a[0-5]b','a1111111b a3b a1b a0b a4b a9b aXb a b a
    b',re.DOTALL))
    # print(re.findall('a[0-9a-zA-Z]b','a1111111b axb a3b a1b a0b a4b a9b aXb a b a
    b',re.DOTALL))
    #
    # print(re.findall('a[^0-9a-zA-Z]b','a1111111b axb a3b a1b a0b a4b a9b aXb a b a
    b',re.DOTALL))
    # print(re.findall('a-b','a-b aXb a b a
    b',re.DOTALL))
    print(re.findall('a[-0-9
    ]b','a-b a0b a1b a8b aXb a b a
    b',re.DOTALL))
    
    
  • 相关阅读:
    app.config应该放哪?
    Connection 和Dispose的学习日志
    简单的sqlhelper的学习日志
    EF 事务(非分布式事务)
    Angularjs 地址联动2.1.1
    C# 如何物理删除有主外键约束的记录?存储过程实现
    C# 枚举基本用法及扩展方法
    JS 去除重复元素的方法
    MVC4程序运行报错
    ASP.NET MVC4 & Entity Framework 6.0 IIS 部署出错解决方案
  • 原文地址:https://www.cnblogs.com/Henry121/p/12615830.html
Copyright © 2011-2022 走看看