• python模块和规范开发


    模块

    1.什么是模块?

    一个模块就是一个py文件。

    模拟博客园系统作业,100000行代码. 不可能全部存在一个文件.

    1. 不易维护.
    2. 效率低.

    分文件: 10个文件.每个文件有50个函数,有一写相同功能或者相似功能的函数.代码冗余,重复性.我们应该将这10个函数提取出来,放在一个文件中,随用随拿.

    2.模块的优点

    1. 节省代码.
    2. 容易维护,组织结构更清晰.

    一个模块就是一个py文件,这个模块存储很多相似的功能,相似的函数的集合体.

    3.模块的分类:

    • 内置模块,标准库.python解释器自带的,time,os,sys,等等.200多种.
    • 第三方库(模块),各种大神写的一些模块,通过pip install....安装.6000种.
    • 自己写的模块.自定义模块.

    4.import

    # import tbjx
    # # 当我引用tbjx模块的时候,实际上将tbjx.py执行一遍,加载到内存.
    # import tbjx
    # import tbjx
    # import tbjx
    # import tbjx
    # import tbjx
    
    # 只是第一次引用时,将此模块加载到内存.
    
    1. 执行文件:02 模块import

    2. 被引用文件(模块): tbjx.py

    3. 第一次导入模块发生的三件事

      import tbjx
      n = 1
      # 引用模块发生三件事.
      '''
          1. 将tbjx.py文件加载到内存.
          2. 在内存中创建一个以tbjx命名的名称空间.
          3. 通过tbjx名称空间的名字.等方式引用此模块的名字(变量,函数名,类名等等).
      '''
      
      # print(tbjx.name)
      # tbjx.read1()
      # tbjx.read2()
      
    4. 被导入模块有独立的名称空间

      # 坑:通过tbjx.的方式引用此模块的名字时,一定一定是从此模块中寻找.
      # 通过import 引用模块 他有自己的独立名称空间,与当前执行文件没有关系.
      name = '李业'
      print(tbjx.name)
      
      def read1():
          print('in 02 模块import')
      
      tbjx.read1()
      
    5. 为模块起别名

      起别名:将一个比较长的模块名化简成简单的.
      # import tbjx as cb
      # ##1 书写方便.
      # import tbjx as tb
      # print(tb.name)
      # tb.read1()
      # ##2 简化代码.
      # content = input('>>>').strip()
      # if content == 'mysql':
      #     import mysql_
      #     mysql_.sqlprase()
      # elif content == 'oracle':
      #     import oracle_
      #     oracle_.sqlprase()
      
      # content = input('>>>').strip()
      #
      # if content == 'mysql':
      #     import mysql_ as db
      # elif content == 'oracle':
      #     import oracle_ as db
      #
      # db.sqlprase()  # 统一化接口
      
      
    6. 导入多个模块

       引入多个模块
      # import time,os,sys  # 不推荐.
      import time
      import os
      import sys
      
      # 易于阅读 易于编辑 易于搜索 易于维护。
      

    5.from... import...

    # from tbjx import name
    # from tbjx import read1
    # print(globals())
    # 相当于从tbjx模块的全局空间中将name,read1变量与值的对应关系
    # 复制到当前执行文件的全局名称空间中.
    # print(name)#name是复制一份过来
    # read1()#是复制了read1的函数内存地址
    
    # 优点:使用起来方便了.
    # 缺点:容易与当前执行文件产生覆盖效果.
    
    1. from... import...的使用

      #from 文件夹 impot 文件名
      #可以用文件名.函数名进行操作
      # 特殊情况:极值情况,工作中不会出现.(了解)
      # 因为如果你要是引用一些模块的变量,那么执行文件中就不应该出现同名变量.
      
    2. from... import...与import对比

    3. 一行导入多个

      # from tbjx import name
      # from tbjx import read1
      
    4. from... import *

      # from ... import *  尽量别单独用
      # from tbjx import *
      # print(name)
      # read1()
      # read2()
      # 1,全部将tbjx的所有名字复制过来,无用功.
      # 2,容易覆盖.
      
      # from ... import * 与__all__配合使用(写在模块文件中)
      

    6.py文件的两种功能

    1. py文件的第一个功能:执行文件(承载代码) 脚本.

      直接打印__name__返回__main__

    2. py文件的第二个功能: 模块(被执行文件).

      直接打印__name__返回tbjx 模块名

    作用:用来控制.py文件在不同的应用场景下执行不同的逻辑(或者是在模块文件中测试代码)

    7.模块的搜索路径

    寻找模块的路径: 内存 ----> 内置模块  ---> sys.path中找
    # 只要这三个地方:内存 内置模块 sys.path可以找到这个引用的模块的路径,这个模块就可以直接引用到.
    # import sys
    # # print(sys.path)
    # # import tbjx
    # print(sys.modules)
    
    # 如何引用到tbjx1.py
    import sys
    # print(sys.path)
    sys.path.append(r'D:s23day15')
    # import tbjx
    import tbjx1
    tbjx1.read1()
    

    序列化模块

    序列化:将一个数据结构(list,dict....)转化成一个特殊的序列(特殊的字符串)的过程.

    # l1 = [1, 2, 3]
    # ret = str(l1)
    # print(ret,type(ret))
    # print(eval(ret))  # 不让用
    
    # 文件存取时,遇到的矛盾.
    # dic ={'username': '太白', 'password': 123}
    
    # dic = {1: {'username': '太白', 'password': 123,'status': False},
    #        2:{'username': 'alex', 'password': 123,'status': False}
    #        }
    
    # 这个字典能放在全局么?
    # with open('register.json',encoding='utf-8',mode='w') as f1:
    #     f1.write(str(dic))
    # with open('register',encoding='utf-8') as f1:
    #     ret = f1.read()
    #     print(ret,type(ret))
    #
    # # 数据结构 --- > str() 存储在文件, 读取出来时,反转不回去.
    # # 网络传输.
    # l1 = [i for i in range(100000)]
    # # 凡是数据通过网络传出去最终的格式必须bytes
    # s1 = str(l1)
    # b1 = s1.encode('utf-8')
    # print(b1)  # b1可以发送出去
    #
    # s2 = b1.decode('utf-8')
    # print(s2,type(s2))
    # s2 转化不成列表了.
    
    # 我们现在要解决的问题: 如果有一种特殊的字符串,这个字符串可以与任何的数据结构互相转换.
    

    序列化模块分类:

    # 序列化模块: 将一中数据结构转化成特殊的序列(特殊的字符串,bytes)并且还可以反转回去.
    
        # json模块: 是所有语言公认的一种序列.最最常用的
        #所以支持的python数据结构有限: int str bool dict list(tuple),None,float
    
        # None  ---> Null ----> NUll
        # dict  --->
        # pickle模块: 只能python语言中使用的,序列化模块:
        # 支持python所有的数据类型以及对象.
        # shevle模块(不讲): 课下了解(只能是文件存取).
    

    json序列化:

    两对四个方法:

    dumps,loads 主要用于网络传输,可以用于文件的存取.

    import json
    # dumps,loads 主要用于网络传输,可以用于文件的存取.
    # dic = {'username': '太白', 'password': 123,'status': False}
    # ret = json.dumps(dic)
    # # print(ret,type(ret))
    
    # ret_dict = json.loads(ret)
    # print(ret_dict)
    
    # 特殊的参数
    # dic = {'username': '太白', 'password': 123,'status': False}
    # # print(dic)
    # ret = json.dumps(dic,ensure_ascii=False,sort_keys=True)
    # print(ret,type(ret))
    # import json
    # dic = {'username': '太白', 'password': 123,'status': False}
    # s_dict = json.dumps(dic)
    # with open('jsonlx.json',encoding='utf-8',mode='w') as f1:
    #     f1.write(s_dict)
    #
    # with open('jsonlx.json',encoding='utf-8') as f2:
    #     content = f2.read()
    #     print(json.loads(content))
    

    多个数据如何存储到一个文件中?

    import json
    # dic1 = {'username': '太白', 'password': 123,'status': False}
    # dic2 = {'username': 'alex', 'password': 123,'status': False}
    # dic3 = {'username': 'ly', 'password': 123,'status': False}
    # with open('jsonmore.json',encoding='utf-8',mode='a') as f1:
    #     f1.write(f'{json.dumps(dic1)}
    {json.dumps(dic2)}
    {json.dumps(dic3)}')
    
    # with open('jsonmore.json',encoding='utf-8') as f1:
    #     for line in f1:
    #         ret = json.loads(line)
    #         print(ret,type(ret))
    

    pickle序列化:python专用

    pickle序列化:
    
    dumps,loads 只能是网络传输
    
    import pickle
    
    # dumps,loads  只能是网络传输
    # l1 = ['wusir', '太白', '小黑', 666]
    # ret = pickle.dumps(l1)
    # # print(ret)
    #
    # l2 = pickle.loads(ret)
    # print(l2,type(l2))
    dump load 数据结构存取文件.
    
    import pickle
    # l1 = ['wusir', '太白', '小黑', 666]
    # with open('pickle练习.pickle',mode='wb') as f1:
    #     pickle.dump(l1,f1)
    
    # with open('pickle练习.pickle', mode='rb') as f1:
    #     ret = pickle.load(f1)
    #     print(ret,type(ret))
    
    # 多个数据写入文件
    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)
    

    os模块

    # 目录: 文件夹.
    # 工作目录,当前目录,父级目录: day17
    
    import os
    # print(os.getcwd())  # D:s23day17 绝对路径  ***
    # os.chdir(r'D:s23day9')
    # print(os.getcwd())
    # print(os.curdir)
    # print(os.pardir)
    
    # 和文件夹相关  ***
    import os
    # os.makedirs('dirname1/dirname2/dirname3/dirname4')  # 多级目录
    # os.removedirs('dirname1/dirname2/dirname3/dirname4') # 截止到有文件的那层
    # os.mkdir(r'd:abc') # 单级目录
    # os.rmdir('abc')
    # print(os.listdir(r'D:s23day15'))
    
    #
    # os.remove()  删除一个文件  ***
    # os.rename("oldname","newname")  重命名文件/目录  ***
    # print(os.stat(r'D:s23day171 昨日内容回顾.py'))
    
    # path 和路径相关  ***
    # print(os.path.abspath('04 os模块.py'))  # D:s23day171 昨日内容回顾.py
    # print(os.path.split(os.path.abspath('01 昨日内容回顾.py')))  # ('D:\s23\day17', '01 昨日内容回顾.py')
    # print(os.path.dirname(r'D:s23day91 初始函数.py'))  # 获取父级目录
    # print(os.path.dirname(os.path.abspath('01 昨日内容回顾.py')))
    # print(__file__)  # 动态获取当前文件的绝对路径
    # 获取当前文件的爷爷级的目录
    # print(os.path.dirname(os.path.dirname(__file__)))
    # print(os.path.basename(r'D:s23day91 初始函数.py'))  # 获取文件名
    # print(os.path.exists(r'D:s23day92 初始函数.py'))
    # 判断是否是绝对路径
    # print(os.path.isabs(r'D:s23day91 初始函数.py'))
    # print(os.path.isabs(r'day17/01 昨日内容回顾.py'))
    # 判断该路径是否是一个文件路径
    # print(os.path.isfile(r'D:s23day91 初始函数.py'))
    # print(os.path.isfile(r'D:s23day9'))
    # print(os.path.isdir(r'D:s23day17dirname1dirname2'))
    # print(os.path.exists(r'D:s23day17dirname1dirname2'))
    # 判断是否是一个目录(文件夹)
    # print(os.path.isdir(r'D:s23day172 序列化模块.py'))
    # D:s23day16评论文章
    # path = os.path.join('D:','s23','day20','随便')
    # print(path)
    # par_dir = os.path.dirname(__file__)
    # print(par_dir)  # D:/s23/day17
    # path = r'D:s23day17dblydata'
    # path = par_dir + 'db' +'lydata'
    # path = os.path.join(par_dir,'db','lydata')
    # with open(path,encoding='utf-8',mode='a') as f1:
    #     f1.write('李业在红浪漫消费998元')
    
    # print(os.path.getatime('D:s23day17dblydata'))
    # print(os.path.getmtime('D:s23day17dblydata'))
    # print(os.path.getsize('D:s23day17dblydata'))
    
    # print(os.stat(r'D:s23day171 昨日内容回顾.py'))
    

    sys模块

    import sys
    # sys.path  ***
    # print(sys.version)  # 版本
    
    # for i in range(3):
    #     print(i)
    # # exit()  # 强制退出
    # # quit()
    # for i in range(5):
    #     print(i)
    
    # print(sys.platform)
    

    hashlib模块

    加密模块, 摘要算法,散列算法,等等.它是一堆加密算法的集合.

    liye|zmdsb

    太白|123

    明文形式存储的,带来安全隐患.

    hashlib如何加密?

    1. 将一个bytes类型的数据 通过hashlib进行加密返回 一个等长度的16进制数字.
    2. 过程不可逆.
    3. 相同的bytes类型的数据通过相同的加密方法得到的数字绝对相同.
    4. 不相同的bytes类型的数据通过相同的加密方法得到的数字绝对不相同.

    撞库: 111111, 123456, 000000,19980123,

    {'202cb962ac59075b964b07152d234b70': 123456}

    hashlib 的用途:

    1. 密码加密.
    2. 文件一致性校验.

    密码加密:

    # 密码加密
    # md5
    # ret = hashlib.md5()
    # ret.update('123'.encode('utf-8'))
    # s = ret.hexdigest()
    # print(s,type(s))
    
    
    
    # 撞库
    
    # ret = hashlib.md5()
    # ret.update('123456*@qwe'.encode('utf-8'))
    # s = ret.hexdigest()
    # print(s,type(s))
    
    # 加固定盐
    # 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))
    #
    

    文件的一致性校验:

    # low版
    # import hashlib
    # ret = hashlib.md5()
    # with open('MD5文件校验',mode='rb') as f1:
    #     content = f1.read()
    #     ret.update(content)
    # print(ret.hexdigest())
    #
    
    
    # 分步update
    # s1 = '老男孩教育 最好的python 讲师 是 太白'
    #
    # 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
    
    
    
    # 高达上版,也可以用for
    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'))
    

    规范开发

    conf文件夹:

    settings.py:

    配置文件,就是放置一些项目中需要的静态参数,比如文件路径,数据库配置,软件的默认设置等等

    lib文件夹:

    common.py:

    公共组件文件,这里面放置一些我们常用的公共组件函数,并不是我们核心逻辑的函数,而更像是服务于整个程序中的公用的插件,程序中需要即调用。比如我们程序中的装饰器auth,有些函数是需要这个装饰器认证的,但是有一些是不需要这个装饰器认证的,它既是何处需要何处调用即可。比如还有密码加密功能,序列化功能,日志功能等这些功能都可以放在这里。

    core文件夹:

    src.py:

    这个文件主要存放的就是核心逻辑功能,你看你需要进行选择的这些核心功能函数,都应该放在这个文件中。

    bin文件夹:

    start.py:

    项目启动文件。你的项目需要有专门的文件启动,而不是在你的核心逻辑部分进行启动的

    db文件夹

    register:

    这个文件文件名不固定,register只是我们项目中用到的注册表,但是这种文件就是存储数据的文件,类似于文本数据库,那么我们一些项目中的数据有的是从数据库中获取的,有些数据就是这种文本数据库中获取的,总之,你的项目中有时会遇到将一些数据存储在文件中,与程序交互的情况,所以我们要单独设置这样的文件。

    log文件夹:

    access.log

    log文件顾名思义就是存储log日志的文件。日志我们一会就会讲到,日志主要是供开发人员使用。比如你项目中出现一些bug问题,比如开发人员对服务器做的一些操作都会记录到日志中,以便开发者浏览,查询。

    README

    说明文件

    time模块

    与时间相关的模块:

    三种形式:

    1. 时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型

    2. 人类看得懂的时间,格式化时间. 2019-6-28 12:00

    3. 结构化时间: python语言使用的,解释器使用的

      元组(struct_time) :struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天等)

    # print(time.time())当前的时间戳
    # 格式化时间:
    # 字符串类型
    # print(time.strftime("%Y-%m-%d %H:%M:%S"))
    # print(time.strftime("%y-%m-%d %H:%M:%S  %A"))
    # ret = time.strftime("%Y{}%m{}%d{} %H:%M:%S")
    # print(ret)
    # print(ret.format('年','月','日'))
    #结构化时间
    # print(time.localtime())
    
    
    # 时间戳 转化成 格式化时间
    # timestamp = time.time()当前时间戳
    # st = time.localtime(timestamp)时间戳转结构化时间
    # # print(st)
    # ft = time.strftime("%y-%m-%d %H:%M:%S",st)结构化时间转格式化时间
    # print(ft)
    
    
    # 格式化时间转化成时间戳
    # ft = time.strftime("%y-%m-%d %H:%M:%S")当前格式化的时间
    # # print(ft)
    # st = time.strptime(ft,"%y-%m-%d %H:%M:%S")格式化时间转结构化时间
    # # print(st)
    # timestamp = time.mktime(st)结构化时间转时间戳
    # print(timestamp)
    

    random模块

    import random
    # print(random.random())  # 大于0且小于1之间的小数
    # print(random.uniform(1, 6))  # ***
    
    # print(random.randint(1,5))  # 1    5 可以取到  ***
    # print(random.randrange(1,10,2))  # 顾头不顾尾  ***
    
    # print(random.choice(['如花', '凤姐', '石榴姐', 1]))  # ***
    # print(random.sample(('如花', '凤姐', '石榴姐'), 3))  # 可以控制元素个数  ***
    
    # 打乱顺序
    # item = [i for i in range(10)]
    # random.shuffle(item)
    # print(item)
    

    datatime模块

    import datetime
    # from datetime import datetime
    # time_now = datetime.datetime.now()
    # print(str(time_now), type(time_now))
    #
    # print(datetime.datetime.now() + datetime.timedelta(weeks=3))三周后
    # print(datetime.datetime.now() + datetime.timedelta(weeks=-4))四周前
    # print(datetime.datetime.now() + datetime.timedelta(days=-15))15天前
    
    # current_time = datetime.datetime.now()
    # print(current_time.replace(year=1979))1979年的现在
    # print(current_time.replace(year=1989,month=4,day=25))1989年四月25日的这个时间
    
    # print(datetime.date.fromtimestamp(4332543543))这个时间戳的格式化时间
    

    包的使用

    # 创建一个包,也会发生三件事:
    
        1. 将该aaa包内 __init__py文件加载到内存.
        2. 创建一个以aaa命名的名称空间.
        3. 通过aaa. 的方式引用__init__的所有的名字.
    
    
          time模块 一个py文件,200个函数,功能特别多,分文件,分三个文件,time文件夹: time1 time2 time3py文件,这个time文件夹就叫做包.
    
          1. import
          2. from ... import ...
          3. 相对导入与绝对导入
    
    
    
    1. # from ... import ...
      # 通过这种方式不用设置__init__文件
      # from aaa import m1
      # m1.func()
      
      # from aaa.bbb.m2 import func1
      # func1()
      # from aaa.bbb import m2
      # m2.func1()
      
      # from a.b.c import d   #.e.f
      # c的. 的前面一定是包
      # import 的后面一定是名字,并且不能 再有点
      

    logging 日志

    工作日志分四个大类:

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

    2. 网站日志: 访问异常,卡顿,网站一些板块,受欢迎程度,访问量,点击率.等等,蜘蛛爬取次数等等.

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

    4. 记录用户信息日志: 用户的消费习惯,新闻偏好,等等.(数据库解决)

      日志: 是谁使用的? 一般都是开发者使用的.

      三个版本:

    5. Low版(简易版).

      import logging
      logging.basicConfig(
          # level=logging.DEBUG
          level=10,
          format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
          # filename=r'test.log',写入文件文件名
      )
      logging.debug("调试")
      logging.info("正常")
      logging.warning("警告")
      logging.error("报错")
      logging.critical("严重跑路")
      
      
    6. 标配版(标准版)

      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 %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
      fh.setFormatter(formatter1)
      sh.setFormatter(formatter2)
      logger.addHandler(fh)
      logger.addHandler(sh)
      #总开关
      logger.setLevel(10)
      
      fh.setLevel(10)
      sh.setLevel(10)
      
      logging.debug("调试")
      logging.info("正常")
      logging.warning("警告")
      logging.error("报错")
      logging.critical("严重跑路")
      
    7. 旗舰版(项目中使用的,Django项目) ***

      1. 自定制(通过字典的方式)日志
      2. 轮转日志的功能.
      import logging.config
      
      # 定义三种日志输出格式 开始
      
      standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' 
                        '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
      
      simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
      
      id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
      
      # 定义日志输出格式 结束
      logfile_name = 'login.log'  # log文件名
      logfile_path_staff = r'D:s23day19日志模块旗舰版日志文件夹staff.log'
      logfile_path_boss = r'D:s23day19日志模块旗舰版日志文件夹oss.log'
      
      # log配置字典
      # LOGGING_DIC第一层的所有的键不能改变
      
      LOGGING_DIC = {
          'version': 1,  # 版本号
          'disable_existing_loggers': False,  # 固定写法
          'formatters': {
              'standard': {
                  'format': standard_format
              },
              'simple': {
                  'format': simple_format
              },
              'id_simple':{
                  'format': id_simple_format
              }
          },
          'filters': {},
          'handlers': {
              #打印到终端的日志
              'sh': {
                  'level': 'DEBUG',
                  'class': 'logging.StreamHandler',  # 打印到屏幕
                  'formatter': 'id_simple'
              },
              #打印到文件的日志,收集info及以上的日志
              'fh': {
                  'level': 'DEBUG',
                  'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                  'formatter': 'standard',
                  'filename': logfile_path_staff,  # 日志文件
                  'maxBytes': 5000,  # 日志大小 5M
                  'backupCount': 5,
                  'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
              },
              'boss':
                  {
                      'level': 'DEBUG',
                      'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                      'formatter': 'id_simple',
                      'filename': logfile_path_boss,  # 日志文件
                      'maxBytes': 5000,  # 日志大小 5M
                      'backupCount': 5,
                      'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
                  },
          },
          'loggers': {
              #logging.getLogger(__name__)拿到的logger配置
              '': {
                  'handlers': ['sh', 'fh', 'boss'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                  'level': 'DEBUG',
                  'propagate': True,  # 向上(更高level的logger)传递
              },
          },
      }
      
      
      def md_logger():
          logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
          logger = logging.getLogger()  # 生成一个log实例
          return logger
          # logger.debug('It works!')  # 记录该文件的运行状态
      
      dic = {
          'username': '小黑'
      }
      
      
      def login():
          # print('登陆成功')
          md_logger().info(f"{dic['username']}登陆成功")
      #
      # def aricle():
      #     print('欢迎访问文章页面')
      
      
      login()
      # aricle()
      

    re模块(正则)

    import re
    # re.findall()
    # 正则表达式: 从一大堆字符串中,找出你想要的字符串.
    # 在于对你想要得这个字符串进行一个精确地描述.
    
    # s1 = 'fdsa太白金星'
    # print(s1.find('白'))
    
    # 单个字符匹配
    # W与w
    # w 数字字母下划线中文
    # W 非数字字母下划线中文
    # print(re.findall('w', '太白jx 12*() _'))
    # print(re.findall('W', '太白jx 12*() _'))
    
    # s  匹配的 空格 	 
    
    # S  匹配的 非空格 	 
    
    # print(re.findall('s','太白barry*(_ 	 
    '))
    # print(re.findall('S','太白barry*(_ 	 
    '))
    
    # 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'))
    
    # ,从结尾开始匹配
    # z,有一点问题
    # $从结尾开始匹配
    # 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'))
    
    # finditer
    ret = re.finditer('d','54fjdkls4535lsdfj6776')
    # print(ret)
    # print(next(ret))
    # print(next(ret).group())
    # print(next(ret).group())
    # for i in ret:
    #     print(i.group())
    # print(list(ret))
    s1 = '''
    时间就是f4321995-04-27,2005-04-27
    1999-04-27 老男孩教育创始人
    老男孩老师 alex 1980-04-27:1980-04-27
    2018-12-08
    '''
    # print(re.findall('d{4}-d{2}-d{2}',s1))
    
    #
    # 匹配一个qq账号 10000开始 第一个元素规定就是非零数字,后面的是随意的数字长度大于5位.
    s2 = '56546326546757'
    print(re.findall('[1-9][0-9]{4,}',s2))
    
  • 相关阅读:
    Python基本命名规范
    复制当前文件夹下所有文件的名称
    Java中返回类型方法名
    BugFree 测试管理系统
    jmeter+badboy免费测试
    Linux的命令
    C语言
    linux基础知识点以及安装
    JMeter安装教程
    linux 操作命令
  • 原文地址:https://www.cnblogs.com/nieice/p/11158008.html
Copyright © 2020-2023  润新知