zoukankan      html  css  js  c++  java
  • 7.19包与模块

    1.模块的三种来源

      (1)内置的

      (2)第三方的

      (3)自定义的

    2.模块的四种表现形式

      (1)py文件

      (2)共享库

      (3)文件夹(一系列模块的结合体)

      (4)C++编译的连接到python内置的

    3.什么是包

      它是一系列模块文件的结合体,表示形式就是一个文件夹,该文件夹内部通常会有一个__init__.py文件,包的本质还是一个模块

    4.首次导入包发生哪些事

      先产生一个执行文件的名称空间

        (1)创建包下面的__init__.py文件的名称空间

        (2)执行包下面的__init__.py文件中的代码,将产生的名字放入包下面的__init__.py文件的名称空间中

        (3)在执行文件中拿到一个指向包下面的__init__.py文件名称空间的名字

    5.当你作为包的设计者来说

      (1)模块的功能特别多的情况下,应该分文件管理

      (2)每个模块之间为了避免后期模块改名的问题,你可以使用相对导入(包里面的文件都应该是被导入的模块)

    6.站在包的开发者角度

      如果使用绝对路径来管理的自己的模块,那么它只需要永远以包的路径为基准依次导入模块

       站在包的使用者角度

      你必须得将包所在的那个文件夹的路径添加到system path中(系统环境变量中)

    7.python2和python3区别

      (1)python2如果要导入包 包下面必须要有__init__.py文件

      (2)python3如果要导入包,包下面没有__init__.py文件也不会报错

    注意:当你在删程序不必要的文件的时候,千万不要随意删除__init__.py文件

    logging模块(日志模块)

    1.日志分为五个等级(等级:可以理解为地震的强度)

      (1)调试:logging.debug('debug日志')  # 10  

      (2)也是正常的操作:logging.info('info日志')  # 20

      (3)警告:logging.warning('warning日志')  # 30

      (4)报错,有错误提示了:logging.error('error日志')   # 40

      (5)严重错误,BUG:logging.critical('critical日志')  # 50

    2.日志需要了解的的对象

      (1)logger对象:负责产生日志

      (2)filter对象:过滤日志(了解)

      (3)handler对象:控制日志输出的位置(文件/终端)

      (4)formmater对象:规定日志内容的格式

    3.用法

    import logging
    # 1.logger对象:负责产生日志
    logger = logging.getLogger('转账记录')
    # 2.filter对象:过滤日志(了解)
    
    # 3.handler对象:控制日志输出的位置(文件/终端)
    hd1 = logging.FileHandler('a1.log',encoding='utf-8')  # 输出到文件中
    hd2 = logging.FileHandler('a2.log',encoding='utf-8')  # 输出到文件中
    hd3 = logging.StreamHandler()  # 输出到终端
    
    # 4.formmater对象:规定日志内容的格式
    fm1 = logging.Formatter(fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',datefmt='%Y-%m-%d %H:%M:%S %p',)
    fm2 = logging.Formatter(fmt='%(asctime)s - %(name)s:  %(message)s',datefmt='%Y-%m-%d',)
    
    # 5.给logger对象绑定handler对象
    logger.addHandler(hd1)
    logger.addHandler(hd2)
    logger.addHandler(hd3)
    
    # 6.给handler绑定formmate对象
    hd1.setFormatter(fm1)
    hd2.setFormatter(fm2)
    hd3.setFormatter(fm1)
    
    # 7.设置日志等级
    logger.setLevel(20)
    
    # 8.记录日志
    logger.debug('记录的内容')

    日志配置字典

    import os
    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'
    # 定义日志输出格式 结束
    
    """
    下面的两个变量对应的值 需要你手动修改
    """
    logfile_dir = os.path.dirname(__file__)  # log文件的目录
    logfile_name = 'a3.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)传递
            },  # 当键不存在的情况下 默认都会使用该k:v配置
        },
    }
    
    # 使用日志字典配置
    logging.config.dictConfig(LOGGING_DIC)  # 自动加载字典中的配置
    logger1 = logging.getLogger('随便用什么都可以')
    logger1.debug('努力就有收获')
    View Code

    hashlib模块(加密的模块

    import hashlib  # 这个加密的过程是无法解密的
    md = hashlib.md5()  # 生成一个帮你造密文的对象
    # md.update('hello'.encode('utf-8'))  # 往对象里传明文数据  update只能接受bytes类型的数据
    md.update(b'hello')  # 往对象里传明文数据  update只能接受bytes类型的数据  等价于上面的
    print(md.hexdigest())  # 获取明文数据对应的密文

      不用的算法,使用方法是相同的(update、hexdigest)。密文的长度越长,内部对应的算法越复杂

      但是:(1)算法越复杂,时间消耗越长

         (2)密文越长,占用空间越大

      所以通常情况下使用md5算法 就可以足够了

    1.传入的内容,可以分多次传入,只要传入的内容相同,那么生成的密文肯定相同

    import hashlib
    md = hashlib.md5()
    md1 = hashlib.md5()
    md.update(b'areyouok?')
    md1.update(b'are')
    md1.update(b'you')
    md1.update(b'ok?')
    print(md.hexdigest())  # 408ac8c66b1e988ee8e2862edea06cc7
    print(md1.hexdigest())  # 408ac8c66b1e988ee8e2862edea06cc7

      hashilib模块应用场景

      (1)密码的密文存储

      (2)校验文件内容是否一致

    2.加盐处理

    import hashlib
    md = hashlib.md5()  # 公司自己在每一个需要加密的数据之前 先手动添加一些内容
    md.update(b'oldboy.com')  # 加盐处理
    md.update(b'hello')  # 真正的内容
    print(md.hexdigest())

    3.动态加盐

      每一次加的盐都不一样,是动态的

    4.定义成函数

    import hashlib
    def get_md5(data):
        md = hashlib.md5()
        md.update('加盐'.encode('utf-8'))
        md.update(data.encode('utf-8'))
        return md.hexdigest()
    password = input('password>>>:')  # 获取用户密码
    res = get_md5(password)  # 调用函数加密
    print(res)

    openpyxl模块

      近几年比较火的操作excel表格的模块

      03版本之前,excel文件的后缀名叫xls;03版本之后,excel文件的后缀名叫xlsx

      以前用来操作excel表格的模块:

        xlwd模块用来写excel

        xlrt模块用来读excel

    区别:xlwd和xlrt既支持03版本之前的excel文件也支持03版本之后的excel文件

       openpyxl只支持03版本之后的excel文件

    1.写

    from openpyxl import Workbook
    wb = Workbook()  # 先生成一个工作簿
    wb1 = wb.create_sheet('index',0)  # 创建一个表单页  后面可以通过数字控制位置
    wb2 = wb.create_sheet('index1')
    wb1.title = 'login'  # 后期可以通过表单页对象点title修改表单页名称
    
    wb1['A3'] = 666  #对应位置写入值
    wb1['A4'] = 444
    wb1.cell(row=6,column=3,value=88888888)  # 第几行第几列写入值
    wb1['A5'] = '=sum(A3:A4)' # 需要自己写函数求值
    
    wb1.append(['username','age','hobby'])  # 写一个表头
    wb1.append(['jason',18,'study'])  # 写表单数据
    wb1.append(['tank',72,'吃生蚝'])  # 写表单数据
    wb1.append(['egon',84,'女教练'])
    wb1.append(['sean',23,'会所'])
    wb1.append(['nick',28,])  # 不写的位置可以直接空出来
    wb1.append(['nick','','秃头'])  # 不写的位置可以直接空出来
    
    # 保存新建的excel文件
    wb.save('test.xlsx')  # 取名保存
    View Code

    2.读

    from openpyxl import load_workbook  # 读文件的模块
    wb = load_workbook('test.xlsx',read_only=True,data_only=True)
    print(wb)
    print(wb.sheetnames)  # ['login', 'Sheet', 'index1']
    print(wb['login']['A3'].value)
    print(wb['login']['A4'].value)
    print(wb['login']['A5'].value)  # 通过代码产生的excel表格必须经过人为操作之后才能读取出函数计算出来的结果值
    
    res = wb['login']  # 另一种读表格方式
    print(res)
    ge1 = res.rows
    for i in ge1:
        for j in i:
            print(j.value)
    View Code

    深浅拷贝

    import copy
    l = [1,2,[1,2]]
    l1 = l
    print(id(l),id(l1))
    l1 = copy.copy(l)  # 拷贝一份 .......  浅拷贝
    print(id(l),id(l1))
    l[0] = 222
    print(l,l1)
    l[2].append(666)
    print(l,l1)
    l1 = copy.deepcopy(l)
    l[2].append(666)
    print(l,l1)
    View Code

    浅拷贝

    深拷贝

  • 相关阅读:
    Codeforces 845E Fire in the City 线段树
    Codeforces 542D Superhero's Job dp (看题解)
    Codeforces 797F Mice and Holes dp
    Codeforces 408D Parcels dp (看题解)
    Codeforces 464D World of Darkraft
    Codeforces 215E Periodical Numbers 容斥原理
    Codeforces 285E Positions in Permutations dp + 容斥原理
    Codeforces 875E Delivery Club dp
    Codeforces 888F Connecting Vertices 区间dp (看题解)
    Codeforces 946F Fibonacci String Subsequences dp (看题解)
  • 原文地址:https://www.cnblogs.com/francis1/p/11215818.html
Copyright © 2011-2022 走看看