zoukankan      html  css  js  c++  java
  • 内置模块

    内置模块

    序列化模块(常用)

    • 本质就是将一种数据结构(如字典、列表)等转换成一个特殊的序列(特殊的字符串或者bytes)并且还可以反转回去的过程就叫做序列化
    • 主要用途:文件读写数据,网络传输数据

    json 模块 ( 通用 ) / str类型

    定义

    • 是所有语言公认的一种序列
    • json序列化只支持部分Python数据结构:dict,list, tuple,str,int, float,True,False,None
    • 存取文件时 文件为 "文件名.json"

    序列化模块中使用最多的的就是json模块

    dumps、loads → 网络传输 / 文件存取 (单 / 多数据)

    import json
    #序列化:json.dumps()
    dic = {'k1':'v1','k2':'v2','k3':'v3'}  # 也可以处理嵌套的数据类型 
    str_dic = json.dumps(dic)  #序列化:将一个字典转换成一个字符串
    print(type(str_dic),str_dic)  #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
    #注意,json转换完的字符串类型的字典中的字符串是由""表示的
    
    #反序列化: json.loads()
    dic2 = json.loads(str_dic)  #反序列化:将一个字符串格式的字典转换成一个字典
    #注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
    print(type(dic2),dic2)  #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
    

    dump、load → 单个数据结构文件存取

    import json
    # json.sump(数据变量,文件句柄) 写入文件
    with open('json_file.json', 'w') as f:
        dic = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
        json.dump(dic, f)  # dump方法接收一个文件句柄,直接将字典转换成json字符串   写入文件
    
    # json文件也是文件,就是专门存储json字符串的文件。
    # json.load(文件句柄)   读出文件
    with open('json_file.json') as f:
        dic2 = json.load(f)  # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
    
    print(type(dic2), dic2) # <class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
    

    json序列化存储单 / 多个数据到同一个文件中

    import json
    # 单个数据 存在 同一个文件中
    import json
    
    dic = {'username': '太白', 'password': 123,'status': False}
    s_dict = json.dumps(dic)
    with open('jsonlx.json',encoding='utf-8',mode='r+') as f1:
        f1.write(s_dict)
        f1.seek(0,0)
        content = f1.read()
        print(json.loads(content))
        #  {'username': '太白', 'password': 123, 'status': False}
    	print(type(json.loads(content)))  # <class "dict">
    
    # 多个数据 存在 同一个文件中
    dic1 = {'name': 'oldboy1'}
    dic2 = {'name': 'oldboy2'}
    dic3 = {'name': 'oldboy3'}
    with open('序列化.json', encoding='utf-8', mode="w") as f:
        str1, str2, str3 = json.dumps(dic1), json.dumps(dic2), json.dumps(dic3)
        f.write(f"{str1}
    {str2}
    {str3}
    ")  # 格式化
    
    # 读取多行文件内容
    
    with open('序列化', encoding='utf-8') as f:
        for line in f:
            print(json.loads(line))
    

    其他参数说明

    ensure_ascii (确认是ASC码?)

    • ensure_ascii = True 非ASCII显示为 uXXXX序列
    • ensure_ascii = False 可正常显示
    • 配合 dump / dumps 使用
    # ensure_ascii = False / True 默认是True
    import json
    dic = {'username': '太白', 'password': 123, 'status': False}
    ret = json.dumps(dic, ensure_ascii=False)
    print(ret)  # {"username": "太白", "password": 123, "status": false} 
    
    ret = json.dumps(dic, ensure_ascii=True) 或者 ret = json.dumps(dic)
    print(ret)  # {"username": "u592au767d", "password": 123, "status": false}
    

    separators 分隔符

    • 第一个分隔符是隔开每个键值对 ,第二个是分隔开每个key和value 默认的就是 原字典 格式分隔符 ( " , : " )
    • 可自定义分隔符
    # separators =  "_?"
    import json
    dic = {'username': '太白', 'password': 123, 'status': False}
    ret = json.dumps(dic) # 默认是字典本身的默认分隔符
    print(ret) # {"username": "u592au767d", "password": 123, "status": false}
    
    ret = json.dumps(dic,separators =  "_?")
    print(ret) # {"username"?"u592au767d"_"password"?123_"status"?false}
    

    sort_keys 排序

    • sort_keys = True 将数据 根据keys的值进行排序
    • sort_keys = False 不排序
    # sort_keys 默认是False 
    import json
    dic = {'username': '太白', 'password': 123, 'status': False}
    
    print(json.dumps(dic) 
    #{"username": "u592au767d", "password": 123, "status": false}
    
    print(json.dumps(dic,sort_keys = True))  # 用key的首字母去排序
    #{"password": 123, "status": false, "username": "u592au767d"}
    

    pickle 模块 (限python) / bytes类型

    定义

    将Python所有的数据结构以及对象等转化成bytes类型,然后还可以反序列化还原回去。

    • 只能是Python语言遵循的一种数据转化格式,只能在python语言中使用
    • 支持Python所有的数据类型包括实例化对象
    • dumps 与 dump 转化成的都是bytes类型数据
    • 存取文件时 文件为 "文件名.pickle"
    • dump / dumps 都是转成bytes类型数据

    dumps、loads → 只用于网络传输

    • 本地(数据类型) dumps → 网络(bytes类型) loads → 接收方(数据类型)
    import pickle
    dic = {'k1':'v1','k2':'v2','k3':'v3'}
    str_dic = pickle.dumps(dic)
    print(str_dic)  # bytes类型
    
    dic2 = pickle.loads(str_dic)
    print(dic2)    # 字典
    

    dump、load → 单 / 多个数据 文件存取

    # 多个数据写入文件
    l1 = ['wusir', '太白', '小黑1', 666]
    l2 = ['wusir', '太白', '小黑2', 666]
    l3 = ['wusir', '太白', '小黑3', 666]
    with open('pickle_1.pickle', mode='wb') as f1:
        pickle.dump(l1, f1)
        pickle.dump(l2, f1)
        pickle.dump(l3, f1)
    
    # 多个数据读取
    with open('pickle_1.pickle', mode='rb') as f1:
        ret1 = pickle.load(f1)
        ret2 = pickle.load(f1)
        ret3 = pickle.load(f1)
        print(ret1, ret2, ret3)
    

    shevle模块 (3.4版新出)

    • 只能在文件存取方面使用

    os模块

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

    sys ( 系统 )模块

    sys.path 返回模块的搜索路径

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

    hashlib模块

    • 摘要算法 / 加密算法 / 哈希算法 / 散列算法 等等

    特征以及使用要点

    • bytes类型数据 → 通过hashlib算法 → 固定长度的字符串
    • 不同的bytes类型数据转化成的结果一定不同
    • 相同的bytes类型数据转化成的结果一定相同
    • 此转化过程不可逆

    用途

    • 密码的加密
    • 文件一致性校验

    hashlib模块就相当于一个算法的集合,这里面包含着很多的算法,算法越高,转化成的结果越复杂,安全程度越高,相应的效率就会越低。

    密码的加密

    # md5 系列
    # 密码加密
    import hashlib
    ret = hashlib.md5()
    ret.update('123'.encode('utf-8'))
    s = ret.hexdigest()
    print(s,type(s)) 
    # 202cb962ac59075b964b07152d234b70 <class 'str'> 加密后的"123"
    
    
    # 加固定盐
    ret = hashlib.md5('xxx教育'.encode('utf-8')) # 加固定的"盐"
    ret.update('123456'.encode('utf-8'))
    s = ret.hexdigest()
    print(s,type(s))
    
    # 加动态的盐
    username = input('输入用户名:').strip()
    password = input('输入密码').strip()
    ret = hashlib.md5(username[::2].encode('utf-8'))  # 加动态"盐"
    ret.update(password.encode('utf-8'))
    s = ret.hexdigest()
    print(s)
    
    
    # sha系列: 安全系数高,耗时高.
    # 加盐,加动态盐
    ret = hashlib.sha512()
    ret.update('123456fdklsajflsdfjsdlkafjafkl'.encode('utf-8'))
    s = ret.hexdigest()
    print(s,type(s))
    
    
    

    文件一致性校验

    import hashlib
    
    s1 = '男孩 最好的python 是 白'
    
    # 1
    ret = hashlib.md5()
    ret.update(s1.encode('utf-8'))
    print(ret.hexdigest())  # 90c56d265a363292ec70c7074798c913
    
    
    # 分步update
    ret = hashlib.md5()
    ret.update('男孩'.encode('utf-8'))
    ret.update(' 最好的python'.encode('utf-8'))
    ret.update(' 是'.encode('utf-8'))
    ret.update(' 白'.encode('utf-8'))
    print(ret.hexdigest())  # 90c56d265a363292ec70c7074798c913
    
    
    

    大文件校验

    import hashlib
    def md5_file(path):
        ret = hashlib.md5()
        with open(path,mode='rb') as f1:
            while 1:
                content = f1.read(1024) # 分开校验 效率快 
                if content:
                    ret.update(content)
                else:
                    return ret.hexdigest()
    
    
    print(md5_file(r'D:s23day17python-3.7.4rc1-embed-win32.zip'))
    
    

    time模块

    在Python中,通常有这三种方式来表示时间:时间戳、元组(struct_time)、格式化的时间字符串:

    • 时间戳
    • 格式化时间
    • 结构化时间

    时间戳 (timestamp) / 计算机能够识别的时间

    • 时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
    • time.time()
    import tmie
    print(time.time()) # 时间戳 1502332424.34242 获取当前时间戳 (type → )
    
    time.sleep(5) # 延迟5秒  推迟指定的时间运行。单位为秒。
    
    
    
    

    格式化时间 / 人能够看懂的时间

    • 格式化的时间字符串(Format String): ‘1999-12-06’
    • time.strftime()
    import time
    print(time.strftime("%Y-%m-%d %H:%M:%S)) # 2019-6-1 12:21:22  字符串类型
    
    print(time.strftime("%y-%m-%d %X")) # 19-06-28 16:00:19
    
    print(time.strftime("%Y-%m-%d %H-%M-%S")) # 2019-06-28 16-01-20 (注意y的大小写)
    
    

    格式化时间 参考代码

    %y 两位数的年份表示(00-99)
    %Y 四位数的年份表示(000-9999)
    %m 月份(01-12)
    %d 月内中的一天(0-31)
    %H 24小时制小时数(0-23)
    %I 12小时制小时数(01-12)
    %M 分钟数(00=59)
    %S 秒(00-59)
    %a 本地简化星期名称
    %A 本地完整星期名称
    %b 本地简化的月份名称
    %B 本地完整的月份名称
    %c 本地相应的日期表示和时间表示
    %j 年内的一天(001-366)
    %p 本地A.M.或P.M.的等价符
    %U 一年中的星期数(00-53)星期天为星期的开始
    %w 星期(0-6),星期天为星期的开始
    %W 一年中的星期数(00-53)星期一为星期的开始
    %x 本地相应的日期表示
    %X 本地相应的时间表示
    %Z 当前时区的名称
    %% %号本身
    
    

    元组(struct_time) 结构化时间 / 用来操作时间的

    • struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)
    • time.localtime()
    import time
    time.localtime()
    #  打印结果 : time.struct_time(tm_year=2019, tm_mon=6, tm_mday=28, tm_hour=16, tm_min=4, tm_sec=40, tm_wday=4, tm_yday=179, tm_isdst=0) / 元组类型
    
    
    索引 Andex 属性 Attribute 值 Values
    0 tm_year (年) 例: 2011
    1 tm_mom (月) 1-12
    2 tm_mday (日) 1-31
    3 tm_hour (时) 0-23
    4 tm_min (分) 0-59
    5 tm_sec (秒) 0-60
    6 tm_wday (weekday) 0-6 / 0表示周一
    7 tm_yday (一年中的第几天) 1-366
    8 tm_isdst (是否是夏令时) 默认为 0

    几种格式之间的转换

    格式化时间 ----> 结构化时间

    # 格式化时间 ---->  结构化时间  
    # ft = time.strftime('%Y/%m/%d %H:%M:%S') ---->  st = time.strptime(ft,'%Y/%m/%d %H:%M:%S')
    
    import time
    ft = time.strftime('%Y/%m/%d %H:%M:%S')  # 格式化时间
    print(ft)# 2019/06/28 16:08:45
    
    st = time.strptime(ft,'%Y/%m/%d %H:%M:%S') # 元组 / 结构化时间
    
    print(st)
    # time.struct_time(tm_year=2019, tm_mon=6, tm_mday=28, tm_hour=16, tm_min=8, tm_sec=45, tm_wday=4, tm_yday=179, tm_isdst=-1)
    
    

    结构化时间 ---> 时间戳

    # 结构化时间 ---> 时间戳
    # st = time.localtime()  ---> t = time.mktime(st)
    
    import time
    st = time.localtime()
    t = time.mktime(st)
    print(t) #  1561709641.0
    
    

    时间戳 ----> 结构化时间

    # 时间戳 ----> 结构化时间
    import time
    t = time.time()
    st = time.localtime(t)
    print(st)
    
    

    结构化时间 ---> 格式化时间

    # 结构化时间 ---> 格式化时间
    import time
    st = time.localtime()
    ft = time.strftime('%Y/%m/%d %H:%M:%S',st)
    print(ft)
    
    

    格式 / 数据转换

    #结构化时间 --> %a %b %d %H:%M:%S %Y串
    #time.asctime(结构化时间) 如果不传参数,直接返回当前时间的格式化串
    >>>time.asctime(time.localtime(1500000000))
    'Fri Jul 14 10:40:00 2017'
    >>>time.asctime()
    'Mon Jul 24 15:18:33 2017'
    
    #时间戳 --> %a %d %d %H:%M:%S %Y串
    #time.ctime(时间戳)  如果不传参数,直接返回当前时间的格式化串
    >>>time.ctime()
    'Mon Jul 24 15:19:07 2017'
    >>>time.ctime(1500000000)
    'Fri Jul 14 10:40:00 2017' 
    
    t = time.time()
    ft = time.ctime(t)
    print(ft)
    
    st = time.localtime()
    ft = time.asctime(st)
    print(ft)
    
    

    计算时间差

    import time
    true_time=time.mktime(time.strptime('2017-09-11 08:30:00','%Y-%m-%d %H:%M:%S'))
    time_now=time.mktime(time.strptime('2017-09-12 11:00:00','%Y-%m-%d %H:%M:%S'))
    dif_time=time_now-true_time
    struct_time=time.gmtime(dif_time)
    print('过去了%d年%d月%d天%d小时%d分钟%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1,
                                           struct_time.tm_mday-1,struct_time.tm_hour,
                                           struct_time.tm_min,struct_time.tm_sec))
    
    

    datetime模块

    • 设置 / 调整 / 修改 时间数据
    # datatime模块
    import datetime
    now_time = datetime.datetime.now()  # 现在的时间
    # 只能调整的字段:weeks days hours minutes seconds
    print(datetime.datetime.now() + datetime.timedelta(weeks=3)) # 三周后
    print(datetime.datetime.now() + datetime.timedelta(weeks=-3)) # 三周前
    print(datetime.datetime.now() + datetime.timedelta(days=-3)) # 三天前
    print(datetime.datetime.now() + datetime.timedelta(days=3)) # 三天后
    print(datetime.datetime.now() + datetime.timedelta(hours=5)) # 5小时后
    print(datetime.datetime.now() + datetime.timedelta(hours=-5)) # 5小时前
    print(datetime.datetime.now() + datetime.timedelta(minutes=-15)) # 15分钟前
    print(datetime.datetime.now() + datetime.timedelta(minutes=15)) # 15分钟后
    print(datetime.datetime.now() + datetime.timedelta(seconds=-70)) # 70秒前
    print(datetime.datetime.now() + datetime.timedelta(seconds=70)) # 70秒后
    
    current_time = datetime.datetime.now()
    # 可直接调整到指定的 年 月 日 时 分 秒 等
    
    print(current_time.replace(year=1977))  # 直接调整到1977年
    print(current_time.replace(month=1))  # 直接调整到1月份
    print(current_time.replace(year=1989,month=4,day=25))  # 1989-04-25 18:49:05.898601
    
    # 将时间戳转化成时间
    print(datetime.date.fromtimestamp(1232132131))  # 2009-01-17
    
    

    random模块 / 随机模块

    import random
    #随机小数
    random.random()      # 大于0且小于1之间的随机小数
    print(random.random())  # 0.7664338663654585
    
    random.uniform(1,3) #大于1小于3的随机小数
    print(random.uniform(1,3)) # 1.6270147180533838
    
    #随机整数
    random.randint(1,5)  # 大于等于1且小于等于5之间的整数
    random.randrange(1,10,2) # 大于等于1且小于10之间的奇数  (可设置步长 例 : 2)
    
    
    #随机选择一个返回
    random.choice([1,'23',[4,5]])  # #1或者23或者[4,5]
    #随机选择多个返回,返回的个数为函数的第二个参数
    random.sample([1,'23',[4,5]],2) # 列表元素任意2个组合
    # [[4, 5], '23']
    
    #打乱列表顺序
    item=[1,3,5,7,9]
    random.shuffle(item) # 打乱顺序 # [5, 1, 3, 7, 9]
    
    #随机字母
    v1=random.randint(65,90) # Ascall码中对应A-Z的是65-90 
    v2=random.randint(97, 122) # # Ascall码中对应a-z的是97-122
    
    

    生成随机验证码

    import random
    
    def v_code():
    
        code = ''
        for i in range(5):
    
            num=random.randint(0,9)
            alf=chr(random.randint(65,90)) # Ascall码中对应A-Z的是65-90 
            alf_1=chr(random.randint(97, 122)) # Ascall码中对应a-z的是97-122
            add=random.choice([num,alf])
            code="".join([code,str(add)])
    
        return code
    
    print(v_code())
    
    

    logging日志

    工作日志四大分类

    系统日志

    • 记录服务器的一些重要信息 / 监控系统 /cpu温度 / 网卡流量 / 重要的硬件的一些指标 / 运维人员经常使用的 / 记录运维人员的一些操作指令 et

    网站日志

    • 访问异常 / 卡顿 / 网站一些板块受欢迎程度 / 访问量 / 点击率 / 蜘蛛爬取次数 et

    辅助开发日志

    • 开发人员在开发项目中利用日志进行排错 排除一些避免不了的错误(记录) / 辅助开发

    记录用户信息日志

    • 用户的消费习惯 / 新闻偏好 et 数据库解决

    日志格式

    • 一般都是开发者使用的

    默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。

    low版(简易版)

    • 缺点:文件与屏幕输入只能二选一
    # 屏幕打印 
    
    import logging
    logging.basicConfig(level=logging.DEBUG) # 相当于 logging.basicConfig(level = 10) / 基本配置
    logging.debug('debug message')
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    '''
    DEBUG:root:debug message
    INFO:root:info message
    WARNING:root:warning message
    ERROR:root:error message
    CRITICAL:root:critical message''' 
    
    # 如不限制告警级别  / logging.basicConfig(level = 10)
    # 打印结果  / 默认告警级别为 warning
    '''
    WARNING:root:warning message
    ERROR:root:error message
    CRITICAL:root:critical message'''
    
    # 输出到文件
    import logging
    logging.basicConfig(
        # level=logging.DEBUG,  # 默认是只显示大于等于WARNING级别的日志
        level=30,   # 限制从 30 处开始记入文件(日志文件后缀.log)
        format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
        filename=r'test.log',)  # 文件叫'test.log',format里前面是限定条件 / 格式 ,后面是文件名
    
    
    logging.debug('调试模式')  # 10
    logging.info('正常模式')  # 20
    logging.warning('警告信息')  # 30  =======
    logging.error('错误信息')  # 40
    logging.critical('严重错误信息')  # 50
    
    
    

    标配版(标准版)

    import logging
    #创建一个logging对象
    logger = logging.getLogger()
    
    #创建一个文件对象 / 输出到文件的文件名 
    fh = logging.FileHandler("标配版.log",encoding = "utf-8")
    
    #创建一个屏幕对象
    sh = logging.StreamHandler()
    
    #配置显示格式   (都可以调数据)      执行时间 /     文件名 /          行数   /  警告级别名
    formatter1 = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')  # 相对数据较多格式
    formatter2 = logging.Formatter('%(asctime)s %(message)s')  # 极简格式 
    fh.setFormatter(formatter1)
    sh.setFormatter(formatter2)
    
    logger.addHandler(fh) # 绑定文件句柄
    logger.addHandler(sh) # 绑定屏幕输出
    
    #总开关 / 先设定总开关 因为默认显示级别为30 
    logger.setLevel(10) # 总设置 限定显示或打印级别
    
    fh.setLevel(10)  # 设置文件显示级别
    sh.setLevel(40)  # 设置屏幕输出级别 
    logger.debug("debug message")
    logger.info("info message")
    logger.warning("warning mesaage")
    logger.error("error message")
    logger.critical("critical message")
    
    

    参数

    logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:
    
    filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
    filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
    format:指定handler使用的日志显示格式。
    datefmt:指定日期时间格式。
    level:设置rootlogger(后边会讲解具体概念)的日志级别
    stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
    
    format参数中可能用到的格式化串:
    %(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用户输出的消息
    
    

    旗舰版 ***

    • (真正项目中使用的,Django项目) 项目中常用
    """
    logging配置
    """
    
    import os
    import logging.config
    
    # 定义三种日志输出格式 开始
    # #1 standard_format 复杂参数格式
                                        # 线程名      # 线程id   # 任务 id
    standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' 
                      '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
        
    # #2 simple_format 简单参数格式
    
    simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
    
    # #3 id_simple_format 极简参数格式
    
    id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
    
    # 定义日志输出格式 结束
    
    logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
    
    logfile_name = 'all2.log'  # log文件名
    
    # 如果不存在定义的日志目录就创建一个
    if not os.path.isdir(logfile_dir):
        os.mkdir(logfile_dir)
    
    # log文件的全路径
    logfile_path = os.path.join(logfile_dir, logfile_name)
    
    # log配置字典  (自己可以自定义设计字典配置)
    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
        },
        'filters': {},
        'handlers': {
            #打印到终端的日志
            'console': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            #打印到文件的日志,收集info及以上的日志
            'default': {
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': logfile_path,  # 日志文件
                'maxBytes': 1024*1024*5,  # 日志大小 5M
                'backupCount': 5,
                'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            },
        },
        'loggers': {
            #logging.getLogger(__name__)拿到的logger配置
            '': {
                'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',
                'propagate': True,  # 向上(更高level的logger)传递
            },
        },
    }
    
    
    def load_my_logging_cfg(a): #可以传参
        logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
        logger = logging.getLogger(__name__)  # 生成一个log实例
        logger.info('It works!')  # 记录该文件的运行状态
        # 或者
        logger.info(a)  # a 为传入参数 可以是自定义格式化内容  被调用时直接使用函数加传参的方式写入或打印到屏幕
    
    # 作为脚本使用
        
    if __name__ == '__main__':   
        load_my_logging_cfg()
    logger配置文件
    
    
    注意注意注意:
    
    
    #1、有了上述方式我们的好处是:所有与logging模块有关的配置都写到字典中就可以了,更加清晰,方便管理
    
    
    #2、我们需要解决的问题是:
        1、从字典加载配置:logging.config.dictConfig(settings.LOGGING_DIC)
    
        2、拿到logger对象来产生日志
        logger对象都是配置到字典的loggers 键对应的子字典中的
        按照我们对logging模块的理解,要想获取某个东西都是通过名字,也就是key来获取的
        于是我们要获取不同的logger对象就是
        logger=logging.getLogger('loggers子字典的key名')
    
        
        但问题是:如果我们想要不同logger名的logger对象都共用一段配置,那么肯定不能在loggers子字典中定义n个key   
     'loggers': {    
            'l1': {
                'handlers': ['default', 'console'],  #
                'level': 'DEBUG',
                'propagate': True,  # 向上(更高level的logger)传递
            },
            'l2: {
                'handlers': ['default', 'console' ], 
                'level': 'DEBUG',
                'propagate': False,  # 向上(更高level的logger)传递
            },
            'l3': {
                'handlers': ['default', 'console'],  #
                'level': 'DEBUG',
                'propagate': True,  # 向上(更高level的logger)传递
            },
    
    }
    
        
    #我们的解决方式是,定义一个空的key
        'loggers': {
            '': {
                'handlers': ['default', 'console'], 
                'level': 'DEBUG',
                'propagate': True, 
            },
    
    }
    
    这样我们再取logger对象时
    logging.getLogger(__name__),不同的文件__name__不同,这保证了打印日志时标识信息不同,但是拿着该名字去loggers里找key名时却发现找不到,于是默认使用key=''的配置
    
    如何拿到logger对象的详细解释
    
    

    collections模块

    namedtuple: 生成可以使用名字来访问元素内容的tuple

    # 但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。 这时,namedtuple就派上了用场:
    from collections import namedtuple
    Point = namedtuple('Point', ['x', 'y'])
    p = Point(1, 2)
    print(p)   # Point(x=1, y=3)  
    print(p.y) # 2
    print(p.x) # 1
    print(p[0]) # 1
    print(p[1]) # 2
    # 具象化字典,让字典更有意义
    
    

    deque : 双端队列,可以快速的从另外一侧追加和推出对象

    • deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈
    • deque除了实现list的append()pop()外,还支持appendleft()popleft(),这样就可以非常高效地往头部添加或删除元素。
    from collections import deque
    q = deque(['a', 'b', 'c'])
    q.append('x') # 默认添加是从尾部添加
    print(q) # deque(['a', 'b', 'c', 'x'])
    q.appendleft('y')
    print(q) # deque(['y', 'a', 'b', 'c', 'x'])
    deque(['y', 'a', 'b', 'c', 'x'])
    
    

    Counter: 计数器,主要用来计数 类似count ***

    Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。

    from collections import Counter
    c = Counter('abcdeabcdabcaba')
    print(c)
    输出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
    
    

    OrderedDict: 有序字典

    • 使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
    • 如果要保持Key的顺序,可以用OrderedDict

    OrderedDict的Key会按照插入的顺序排列,不是Key本身排序

    from collections import OrderedDict
    d = dict([('a', 1), ('b', 2), ('c', 3)])
    d # dict的Key是无序的  {'a': 1, 'c': 3, 'b': 2}
    
    od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    # od# OrderedDict的Key是有序的
    print(d)
    print(OrderedDict([('a', 1), ('b', 2), ('c', 3)]))
    
    od = OrderedDict()
    od['z'] = 1
    od['y'] = 2
    od['x'] = 3 
    print(od.keys()) # 按照插入的Key的顺序返回 odict_keys(['z', 'y', 'x'])
    print(od.values()) # odict_values([1, 2, 3])
    
    

    defaultdict: 带有默认值的字典

    # 有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
    # 即: {'k1': 大于66 , 'k2': 小于66}
    
    

    常规字典解决办法

    li = [11,22,33,44,55,77,88,99,90]
    result = {}
    for row in li:
        if row > 66:
            if 'key1' not in result:
                result['key1'] = []
            result['key1'].append(row)
        else:
            if 'key2' not in result:
                result['key2'] = []
            result['key2'].append(row)
    print(result)
    
    

    defaultdict字典解决方法

    from collections import defaultdict
    
    values = [11, 22, 33,44,55,66,77,88,99,90]
    
    my_dict = defaultdict(list)
    
    for value in  values:
        if value>66:
            my_dict['k1'].append(value)
        else:
            my_dict['k2'].append(value)
    
    

    带默认值的字典 / defaultdict

    使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict

    from collections import defaultdict
    dd = defaultdict(lambda: 'N/A')  # lambda里可设置其他类型默认值
    dd['key1'] = 'abc'
    dd['key1'] # key1存在
    'abc'
    dd['key2'] # key2不存在,返回默认值
    'N/A'
    
    

    re模块

    正则表达式

    从一大堆字符串中 , 找出你想要的字符串

    在对于你想要的这个字符串进行一个精确地描述

    爬虫

    方法太多

    匹配规则特别多

    import re
    # re.findall()
    # 正则表达式: 从一大堆字符串中,找出你想要的字符串.
    # 在于对你想要得这个字符串进行一个精确地描述.
    
    # 单个字符匹配
    # =============
    # W与w
    # w 数字字母下划线中文
    # W 非数字字母下划线中文
    # print(re.findall('w', '太白jx 12*() _'))
    # print(re.findall('W', '太白jx 12*() _'))
    
    # =============
    # s与S
    # s  匹配的 空格 	 
    
    # S  匹配的 非空格 	 
    
    # print(re.findall('s','太白barry*(_ 	 
    '))
    # print(re.findall('S','太白barry*(_ 	 
    '))
    
    # =============
    # d与D
    # d 匹配所有的数字
    # D 非匹配所有的数字
    # print(re.findall('dd','1234567890 alex *(_'))
    # print(re.findall('D','1234567890 alex *(_'))
    
    # =============
    # A ^从开头开始匹配
    # print(re.findall('Ahello','hello hello 太白 hell'))
    # print(re.findall('^hello','hello hello 太白 hell'))
    
    # =============
    # ,从结尾开始匹配
    # $从结尾开始匹配
    # print(re.findall('fjkdsla太白金星','fjkdsla太白金星'))
    # print(re.findall('金星$','fjkdsla太白金星'))
    
    # =============
    # 
     	
    # print(re.findall('
    ','fdsak
     fkjdlas
     	'))
    # print(re.findall('	','fdsak
     fkjdlas
     	'))
    
    
    # 元字符匹配
    
    # . ? * + {m,n} .* .*?
    #  . 匹配任意一个字符
    # 如果匹配成功光标则移到匹配成功的最后的字符
    # 如果匹配未成功光标则向下移动一位再次匹配
    # print(re.findall('a.b','aaabbb'))
    
    # ? 匹配0个或者1个由左边字符定义的片段。
    # print(re.findall('a?b', 'ab aab'))
    # print(re.findall('a?b', 'sb ab aabb'))
    
    # * 匹配0个或者多个左边字符表达式。 满足贪婪匹配
    # print(re.findall('a*b','aaab ab b'))
    # # print(re.findall('a*b','aasab ab b'))
    
    # + 匹配1个或者多个左边字符表达式。 满足贪婪匹配
    # print(re.findall('a+b','aaab ab b'))
    
    # {m,n}  匹配m个至n(n能取到)个左边字符表达式。 满足贪婪匹配
    # print(re.findall('a{1,5}b', 'ab aab aaab aaaab aaaaaab aaaaabb'))
    
    # .* 贪婪匹配 从头到尾.
    # print(re.findall('a.*b','aab abbliye aaab abbb aa#b'))
    # print(re.findall('a.*b','asb abbliyeaaab 
    abbb aa#y',re.DOTALL))  # a...................b
    
    # .*? 此时的?不是对左边的字符进行0次或者1次的匹配,
    # 而只是针对.*这种贪婪匹配的模式进行一种限定:告知他要遵从非贪婪匹配 推荐使用!
    # 0个或者多个
    # print(re.findall('a.*?b','ab a#bbbbbb aaab'))
    # print(re.findall('a.*b','a#bbbbbb'))
    # print(re.findall('a.*?b','a#bbbbbb'))
    
    
    # []
    
    # print(re.findall('a[abc]b', 'aab abb acb adb afb a_b'))
    # print(re.findall('a[abc][bd]b', 'aabb aaabc abd acdbb'))
    
    # print(re.findall('a[0-9]b', 'a1b a3b aeb a*b arb a_b'))
    
    # print(re.findall('a[a-z]b', 'a1b a3b aeb a*b arb a_b'))
    # print(re.findall('a[A-Z]b', 'aAb a3b aEb a*b aRb a_b'))
    # print(re.findall('a[a-zA-Z]b', 'aab a3b aAb a*b aTb a_b'))
    # 当你想匹配 - 时,要把它放在[]里面的最前面或者最后面
    # print(re.findall('a[-*$]b', 'a-b a$b a)b a*b '))
    # ^ 在中括号里面最前面代表取反
    # print(re.findall('a[0-9]b', 'a1b a$b a5b a*b '))
    # print(re.findall('a[*^)]b', 'a^b a$b a5b a*b '))
    
    # 'alex_sb wusir_sb ritian_sb 太白_nb yuanbao_sb'
    s = 'alex_sb wusir_sb ritian_sb 太白_nb yuanbao_sb dsb_sb'
    # print(re.findall('w+_sb',s))
    # # 'alex_sb wusir_sb ritian_sb 太白_nb yuanbao_sb'
    # # ()
    # print(re.findall('(w+)_sb',s))
    
    # |
    # print(re.findall('alex|太白|wusir', 'alex太白wusiraleeeex太太白odlb'))
    
    
    
    # # () 分组里面加了?: 将全部的内容给我返回回来,而不是将组内的内容返回
    # print(re.findall('companies|company',
    #                  'Too many companies have gone bankrupt, and the next one is my company'))  # ['ies', 'y']
    
    # printy companies have gone bankrupt, and the next one is my company'))(re.findall('compan(?:ies|y)',
    # #                  'Too man
    
    
    # search match
    import re
    # 找到第一个符合条件的字符串就返回,返回一个对象,通过对象.group()
    # ret = re.search('sb|alex', 'alex sb sb barry 日天')
    # ret = re.search('alex', 'fdsjkfd fjdsklalex gfdlgjfdlgjfggfjlgjfkdl')
    # # # print(ret)
    # # # print(ret.group())
    #
    # # 从字符串开头匹配,如果以符合条件的字符串开头则返回,否则返回None
    # ret = re.match('alex', 'alexfdskfd fjdsklalex gfdlgjfdlgjfggfjlgjfkdl')
    # print(ret)
    # print(ret.group())
    
    # split
    # s1 = 'alex;wusir,太白 吴超~宝元'
    # import re
    # print(re.split('[;, ~]',s1))
    import re
    # print(re.sub('barry', '太白', 'barry是最好的讲师,barry就是一个普通老师,请不要将barry当男神对待。'))
    
    # obj = re.compile('d{2}')
    # # print(obj.search('fdsa12fds435454').group())
    # print(obj.findall('fjdskalf2134fkjsd3245fdjsl545'))
    
    
    
  • 相关阅读:
    fiddler的使用
    redis pipeline
    redis hash map
    redis队列的实现
    PHP-redis中文文档-命令
    websocket
    c++之socket,阻塞模式
    Django上传文件和修改date格式
    通过字符串导入模块
    'CSRFCheck' object has no attribute 'process_request' 报错
  • 原文地址:https://www.cnblogs.com/fanxss/p/11091454.html
Copyright © 2011-2022 走看看