zoukankan      html  css  js  c++  java
  • 序列化模块、加密模块

    . 昨日内容回顾
    time datetime
    1. time.time()
    2. time.strftime("%Y-%m-%d %H:%M:%S")
    3. time.localtime()

    datetime

    日志:logging
    低配
    标配
    高配

    # 高配版日志
    
    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'
    
    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': {
            # 打印到终端的日志
            # 屏幕句柄
            'screen': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            # 打印到文件的日志,收集info及以上的日志
            # 这里可以添加其他文件句柄,比如 "staff",后面记得也要修改
            'file': {
                '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': ['screen', 'file'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',  # 总级别,一定要设置最低的,即debug
                'propagate': True,  # 向上(更高level的logger)传递
            },
        },
    }
    
    
    def load_my_logging_cfg():
        logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
        # logger = logging.getLogger(__name__)  # 生成一个log实例
        logger = logging.getLogger("转账业务")
        logger.info('It works!')  # 记录该文件的运行状态
    
    if __name__ == '__main__':
        load_my_logging_cfg()
    
    
    
    # 上面的程序要再加一个文件日志,只需在以下几步添加或修改:
    # 第一步:
    # logfile_name = 'all2.log'  # log文件名
    # 
    # 第二步:
    # 'file': {
    #             'level': 'DEBUG',
    #             'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
    #             'formatter': 'standard',
    #             # 第三步:
    #             'filename': logfile_path,  # 日志文件
    #             'maxBytes': 1024*1024*5,  # 日志大小 5M
    #             'backupCount': 5,
    #             'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
    #         },
    #     },
    
    # 第四步:
    # 列表里对应修改。比如在第二步加了 "staff",这里要添加 "staff"
    # 'handlers': ['stream', 'file'],
    
    # 第五步
    # logger = logging.getLogger("转账业务")  # 这里的参数可按需求随便改
    # logger.info('It works!')  # 这里不仅参数可以随便改,logger.info也可以改为 logger.warning 之类的
    
    # 可以有两个 LOGGING_DIC, 然后两个 def load_my_logging_cfg() 当然函数名要不一样,相应那五步也要改过来
    def func():
        """
        这是文档说明
        :return:
        """
        print(__name__)
    
    print(func.__name__)  # func
    print(func.__doc__)
    
    # 这是文档说明
    # :return:
    
    def func():
        """
        这是文档说明
        :return:
        """
        print(func.__name__)
    
    func()  # func
    # 序列化模块(重要)
    # 网络数据传输只能通过 bytes 类型
    # 文件写入内容(注意不是存储)即可以是 bytes, 也可以是 str
    
    dic = {"name": "太白金星", "hobby": ["戒烟", "烫不了头", "戒酒"]}
    s1 = str(dic)
    b1 = s1.encode("utf-8")
    print(b1)
    
    # b"{'name': 'xe5xa4xaaxe7x99xbdxe9x87x91xe6x98x9f', 'hobby': ['xe6x88x92xe7x83x9f', 'xe7x83xabxe4xb8x8dxe4xbax86xe5xa4xb4', 'xe6x88x92xe9x85x92']}"
    
    s2 = b1.decode("utf-8")
    # print(s2, type(s2))
    dic2 = eval(s2)
    print(dic2, type(dic2))
    # {'name': '太白金星', 'hobby': ['戒烟', '烫不了头', '戒酒']} <class 'dict'>
    # 但这是网络传输,使用 eval() 很危险,容易被黑客截取并替换成病毒文件
    # 因此需要一个功能,能将数据转化成可以通过网络传输的 bytes
    
    # 序列化过程——将数据(数据结构,非字符串) 转化成 特殊的字符串(可以用于网络传输)
    # 反序列化过程——另外还得将这个特殊的字符串 转化成 原来的数据结构
    # Python中的序列化模块有三种:
    # import json
        # json 序列化模块是所有语言通用的一种标准,也是一种数据转化格式
        # 也就是说 Python 中的字典,可以通过 json 模块转化成 bytes 来进行网络传输成 java 的字典
        # str, int, bool, dict, list(tuple), None 没有集合
    
    # import pickle
        # pickle 也是序列化模块,但是只支持Python语言中所有数据类型(包括对象)的网络传输(用的少)
        # 写入文件时,可以写入多个
    
    # import shelve  # 了解
        # shelve 序列化模块,只支持Python,一般与文件相关,即通过它把数据写入文件,拿出来后再反解成原数据类型
    # json——安全模式的网络传输
    # 项目中一般使用 json 来写
    
    # 第一对方法:dumps loads
    
    # import json
    dic = {"name": "太白金星", "hobby": ["戒烟", "烫不了头", "戒酒"]}
    # json的序列化过程
    s = json.dumps(dic)
    print(s, type(s))
    
    # # {"name": "u592au767du91d1u661f", "hobby": ["u6212u70df", "u70ebu4e0du4e86u5934", "u6212u9152"]} <class 'str'>
    
    s = json.dumps(dic, ensure_ascii=False)
    print(s)
    # {"name": "太白金星", "hobby": ["戒烟", "烫不了头", "戒酒"]}
    
    # json的反序列化过程
    dic1 = json.loads(s)
    print(dic1, type(dic1))
    # {'name': '太白金星', 'hobby': ['戒烟', '烫不了头', '戒酒']} <class 'dict'>
    
    # 注意
    dic = {"name": "太白金星", "hobby": ["戒烟", "烫不了头", "戒酒"]}
    print(dic)
    # {'name': '太白金星', 'hobby': ['戒烟', '烫不了头', '戒酒']}
    # 字符串都是单引号,不过写的是双引号还是单引号
    # 而上面的json.dumps 用法结果是双引号
    # 第二对 dump load 与文件相关
    
    dic = {"name": "太白金星", "hobby": ["戒烟", "烫不了头", "戒酒"]}
    with open("序列化.json", encoding="utf-8", mode="w") as f:
        # json.dump(dic, f)
        json.dump(dic, f, ensure_ascii=False)
    
    with open("序列化.json", encoding="utf-8") as f2:
        ret = json.load(f2)
    print(ret, type(ret))
    # {'name': '太白金星', 'hobby': ['戒烟', '烫不了头', '戒酒']} <class 'dict'>
    # 参数讲解
    
    # ensure_ascii=False 显示中文
    # sort_keys 按键的首字母的 ascii 排序
    
    import json
    dic = {"name": "太白金星",
           "hobby": ["戒烟", "烫不了头", "戒酒"],
           "age": 18,
           "money": "一个亿"}
    s = json.dumps(dic, ensure_ascii=False, sort_keys=True)
    print(s)
    
    # # {"age": 18, "hobby": ["戒烟", "烫不了头", "戒酒"], "money": "一个亿", "name": "太白金星"}
    # json 与 bytes 的区别
    # bytes 只能操作str,用于网络传输
    # json 可以操作 str, int, bool, dict, list(tuple), None 没有集合,用于网络传输,写入文件
    
    # 通过json将多个字典写入一个文件
    # 如果用 dump load 一个文件只能写入一个数据结构!!!
    
    import json
    
    dic1 = {"name": "abc"}
    dic2 = {"name": "def"}
    dic3 = {"name": "xyz"}
    
    # 下面这样不行
    with open("多个字典.json", encoding="utf-8", mode="w") as f:
        json.dump(dic1, f)
        json.dump(dic2, f)
        json.dump(dic3, f)
    
    with open("多个字典.json", encoding="utf-8") as f1:
        ret1 = json.load(f1)
        ret2 = json.load(f1)
        ret3 = json.load(f1)
    import json
    dic1 = {"name": "abc"}
    dic2 = {"name": "def"}
    dic3 = {"name": "xyz"}
    
    with open("多个字典.json", encoding="utf-8", mode="w") as f:
        f.write(json.dumps(dic1) + "
    ")
        f.write(json.dumps(dic2) + "
    ")
        f.write(json.dumps(dic3) + "
    ")
    # 上面有结果,但是会飘红,不影响后面的操作
    
    with open("多个字典.json", encoding="utf-8") as f1:
        for line in f1:
            print(json.loads(line))
    
    # {"name": "abc"}
    # {"name": "def"}
    # {"name": "xyz"}
    
    
    # 总结
    # dumps loads 用于网络传输和多个数据写入文件
    # dump load 只能用于一个数据结构写入文件
    # 一个小细节
    
    import json
    dic = {1: "alex"}
    t = json.dumps(dic)
    print(t)  # {"1": "alex"}
    # 发现数字1变成字符串形式了
    print(json.loads(t))  # {'1': 'alex'}
    # 还原过后已经没有整数型了
    # 算是一个 bug,一个坑
    # pickle
    
    import pickle
    
    # dums, loads 用于网络传输,把所有数据类型转化成 bytes
    dic = {"name": "太白金星",
           "hobby": ["戒烟", "烫不了头", "戒酒"],
           "age": 18,
           "money": "一个亿"}
    s1 = pickle.dumps(dic)
    # print(s1)
    dic2 = pickle.loads(s1)
    print(dic2, type(dic2))
    
    dic = {"name": "太白金星",
           "hobby": ["戒烟", "烫不了头", "戒酒"],
           "age": 18,
           "money": "一个亿"}
    with open("p1.pickle", mode="wb") as f:
        pickle.dump(dic, f)
    
    with open("p1.pickle", mode="rb") as f1:
        ret = pickle.load(f1)
        print(ret, type(ret))
        # {'name': '太白金星', 'hobby': ['戒烟', '烫不了头', '戒酒'], 'age': 18, 'money': '一个亿'} <class 'dict'>
    # 利用 dump 和 load 将多个数据写入文件,json的不行
    
    dic1 = {"name": "abc"}
    dic2 = {"name": "def"}
    dic3 = {"name": "xyz"}
    
    # 注意这里不用写明 encoding,因为带 b 的不能用!!!
    with open("p2.pickle", mode="wb") as f:
        pickle.dump(dic1, f)
        pickle.dump(dic2, f)
        pickle.dump(dic3, f)
    
    with open("p2.pickle", mode="rb") as f1:
        ret1 = pickle.load(f1)
        ret2 = pickle.load(f1)
        ret3 = pickle.load(f1)
    
    print(ret1, ret2, ret3)
    # {'name': 'abc'} {'name': 'def'} {'name': 'xyz'}
    
    
    def func():
        print(666)
    
    with open("p3.pickle", mode="wb") as f:
        pickle.dump(func, f)
    
    with open("p3.pickle", mode="rb") as f1:
        ret = pickle.load(f1)
    
    ret()  # 666
    # shelve
    # helve也是python提供给我们的序列化工具,比pickle用起来更简单一些。
    # shelve只提供给我们一个open方法,是用key来访问的,使用起来和字典类似。
    
    import shelve
    f = shelve.open('shelve_file')
    f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'}  #直接对文件句柄操作,就可以存入数据
    f.close()
    # 上面相当于给文件写入一个字典,{"key": {'int':10, 'float':9.5, 'string':'Sample data'}}
    # 结果有三个文件
    f = shelve.open('shelve_file')
    existing = f1['key']  #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
    f1.close()
    print(existing)
    # 这个模块有个限制,它不支持多个应用同一时间往同一个DB进行写操作。
    # 所以当应用只进行读操作,可以让shelve通过只读方式打开DB
    
    import shelve
    f = shelve.open('shelve_file', flag='r')
    existing = f['key']
    f.close()
    print(existing)
    
    # 由于shelve在默认情况下是不会记录待持久化对象的任何修改的
    # 所以在shelve.open()时候需要修改默认参数,否则对象的修改不会保存。
    
    import shelve
    f1 = shelve.open('shelve_file')
    print(f1['key'])
    f1['key']['new_value'] = 'this was not here before'
    f1.close()
    
    # 如果想对 shelve 文件进行修改,必须要加这个参数
    f2 = shelve.open('shelve_file', writeback=True)
    print(f2['key'])
    f2['key']['new_value'] = 'this was not here before'
    f2.close()
    # 加密模块 摘要算法 一堆加密算法的集合体
    # hshlib的规则——将 str 通过算法得到一串等长度的 数字
    
    # 1.不同的字符串转化成的数字肯定不同
    # 2.相同的字符串即使在不同的计算机,只要使用相同的加密方式,转化成的数字一定相同
    # 3.hashlib 加密不可逆,不能破解
    
    # 给密码加密
    import hashlib
    # md5
    ret = hashlib.md5()
    ret.update("好123".encode("utf-8"))
    print(ret.hexdigest())
    # 51cb75f82eceb17b86f019e01618d75e
    
    ret = hashlib.md5()
    ret.update("asjdlkajlkajsdlkajljlajsalsj".encode("utf-8"))
    print(ret.hexdigest())
    # 77e2bcc002a6a2a957519303d16a976a
    
    # 可以看出,不管字符串多长,它都是转化成一样长的数字
    
    # 加盐——让密码更复杂
    ret = hashlib.md5("老男孩教育".encode("utf-8"))
    ret.update("123456".encode("utf-8"))
    print(ret.hexdigest())
    # b08404ec951d75b6da37fdd1bfb8c1e9
    
    # 动态盐
    username = input("请输入用户名: ").strip()
    # ret = hashlib.md5(username.encode("utf-8"))
    ret = hashlib.md5(username[::2].encode("utf-8"))
    ret.update("123456".encode("utf-8"))
    print(ret.hexdigest())
    # asdak
    # 331c5caa07f18d43b7c6302202bd4d2d
    # md5 加密效率快,通用,安全性相对差
    # sha 系列,算法更好,安全性高,效率低,耗时长
    
    # sha系列
    ret = hashlib.sha512()
    ret.update("aksdjalksjdalkj".encode("utf-8"))
    print(ret.hexdigest())
    # 093bc658d3b1a40ba2f4b41a8f86cca8cb79f7808e52
    # 75e69303988afd938722f97d5ac4565f2a494d75dabcdbca6
    # 1e446fd7c4a14c29bfa711a7a34fa84d1e2
    
    # 加盐
    ret = hashlib.sha512("好好学习".encode("utf-8"))
    ret.update("aksdjalksjdalkj".encode("utf-8"))
    print(ret.hexdigest())
    # a17ae4ede113d8969df70b5a6547b41164dfcd56423d
    # 4d2a761f625558f22b4791f4808132db994cbc9ec76ccdb
    # 6b3a44d17b71e043fbcbc5584f96f9a38b88d
    
    # 动态盐
    username = input("请输入用户名:").strip()
    ret = hashlib.sha512(username.encode("utf-8"))
    ret.update("aksdjalksjdalkj".encode("utf-8"))
    print(ret.hexdigest())
    # askdj
    # ee97bc4ad328e098fef08395c07309adf7746e37dec81d
    # 2e123d34fa81ffceaaa9c15f4cb2ba8544c5a9217640e0e
    # 48953f12dd0ac820176a3982260ad70fc8f
    # 文件校验
    def check_md5(file):
        ret = hashlib.md5()
        with open(file, encoding="utf-8", mode="rb") as f:
            ret.update(f.read())
            return ret.hexdigest()
    print(check_md5("文件校验1"))
    print(check_md5("文件校验2"))  # 注意一定要有两个文件,内容一样
    # "文件校验1与当前文件在同一个文件夹
    # 这里有个问题,如果文件太大占内存,因此用 for循环hao
    
    
    
    ret = hashlib.md5()
    ret.update("好好学习并且天天向上".encode("utf-8"))
    print(ret.hexdigest())
    
    ret.update("好好学习".encode("utf-8"))
    ret.update("并且".encode("utf-8"))
    ret.update("天天向上".encode("utf-8"))
    print(ret.hexdigest())
    
    # 上面两个结果一样
    # 大文件校验
    # 因此,文件较大时,可以这样写
    # 按照一行一行读取
    
    def check_md5(file):
        ret = hashlib.md5()
        with open(file, mode="rb") as f:
            for line in f:
                ret.update(line)
            return ret.hexdigest()
    print(check_md5("test"))
    print(check_md5("test01"))
    # 8a9a779e5bacbd752fb5deb05581f86e
    # 8a9a779e5bacbd752fb5deb05581f86e
    
    
    # 按照字节读取
    def check_md5(file):
        ret = hashlib.md5()
        with open(file, mode="rb") as f:
            while 1:
                content = f.read(1024)
                # 这个表示每次最多读取这么多字节,而不是每次读取1024个字节
                if content:  # 如果真表示一直能取到内容
                    ret.update(content)
                else:
                    break
                    # 因此这里文件的最后内容不够1024个字节时,把剩下的读取出来,然后退出
            return ret.hexdigest()
    print(check_md5("test"))
    print(check_md5("test01"))
    # 8a9a779e5bacbd752fb5deb05581f86e
    # 8a9a779e5bacbd752fb5deb05581f86e
    os sys 模块
    os模块是与操作系统交互的一个接口
    工作目录,父级目录,当前目录都是此文件从属的文件夹路径
    绝对路径——从根目录到当前文件的文件名
    相对路径——同一个文件夹下的文件的相对关系

    当前执行这个python文件的工作目录相关的工作路径

    获取当前工作目录,即当前python脚本工作的目录路径
    os.getcwd()
    改变当前脚本工作目录;相当于shell下cd
    os.chdir("dirname")
    返回当前目录: ('.')
    os.curdir
    获取当前目录的父目录字符串名:('..')
    os.pardir

    和文件夹相关
    可生成多层递归目录
    os.makedirs('dirname1/dirname2')

    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    os.removedirs('dirname1')

    生成单级目录;相当于shell中mkdir dirname
    os.mkdir('dirname')

    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir
    dirname
    os.rmdir('dirname')

    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    os.listdir('dirname')

    和文件相关
    删除一个文件
    os.remove()

    重命名文件/目录
    os.rename("oldname","newname")

    获取文件/目录信息
    os.stat('path/filename')

    path系列,和路径相关

    返回path规范化的绝对路径
    import os
    os.path.abspath(path)
    print(os.path.abspath("模块.py")) # 获取绝对路径
    G:ATM模块.py
    将path分割成目录和文件名二元组返回
    os.path.split(path)

    返回path的目录。其实就是os.path.split(path)的第一个元素
    os.path.dirname(path)

    返回path最后的文件名。如何path以/或结尾,那么就会返回空值,
    即os.path.split(path)的第二个元素。
    os.path.basename(path)

    如果path存在,返回True;如果path不存在,返回False
    os.path.exists(path)

    如果path是绝对路径,返回True
    os.path.isabs(path)

    如果path是一个存在的文件,返回True。否则返回False
    os.path.isfile(path)

    如果path是一个存在的目录,则返回True。否则返回False
    os.path.isdir(path)

    将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
    os.path.join(path1[, path2[, ...]])

    返回path所指向的文件或者目录的最后访问时间
    os.path.getatime(path)

    返回path所指向的文件或者目录的最后修改时间
    os.path.getmtime(path)

    返回path的大小
    os.path.getsize(path)

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

    import sys
    try:
    sys.exit(1)
    except SystemExit as e:
    print(e)
    collections模块
    在内置数据类型(dictlistsettuple)的基础上
    collections模块还提供了几个额外的数据类型:
    Counter、deque、defaultdict、namedtuple和OrderedDict等。


    # 1.namedtuple: 生成可以使用名字来访问元素内容的tuple
    # 命名元组
    # tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:
    # p = (1, 2)
    # 看到(1, 2),很难看出这个tuple是用来表示一个坐标的,所以应该这样:
    
    from collections import namedtuple
    Point = namedtuple('Point', ['x', 'y'])
    p = Point(1, 2)
    print(p)  # Point(x=1, y=2)
    print(p[0])  # 1
    print(p.x)  # 1
    print(p.x + p.y)  # 3
    
    # 类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:
    # namedtuple('名称', [属性list]):
    Circle = namedtuple('Circle', ['x', 'y', 'r'])
    
    
    
    # 2.deque: 双向队列,可以快速的从另外一侧追加和推出对象,也是数据类型
    # 比如购物时只有前10人有优惠。
    # 使用list存储数据时,按索引访问元素很快
    # 但是插入和删除元素就很慢了,因为list是线性存储
    # 数据量大的时候,插入和删除效率很低。
    
    # 而deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
    from collections import deque
    q = deque(['a', 'b', 'c'])
    q.append('x')  # 从右添加
    q.appendleft('y')  # 从左添加
    print(q)
    # deque(['y', 'a', 'b', 'c', 'x'])
    
    # pop()也一样
    # 3.defaultdict: 带有默认值的字典
    # 有如下值集合 [11,22,33,44,55,66,77,88,99,90...]
    # 将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
    
    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)
    # print(my_dict["key1"])  # []
    # print(my_dict["key2"])  # []
    for value in values:
        if value > 66:
            my_dict["key1"].append(value)
        else:
            my_dict["key2"].append(value)
    print(my_dict)
    # defaultdict(<class 'list'>,
    # {'key2': [11, 22, 33, 44, 55, 66], 'key1': [77, 88, 99, 90]})
    
    # 构建一个字典,字典的key 从1-100,对应的值都是666
    # 第一种方法
    dic = {}
    for i in range(1, 101):
        dic[i] = 666
    print(dic)
    
    # 第二种方法
    dic = dict.fromkeys(range(1, 101), 666)
    print(dic)
    
    # 第三种方法
    # 字典推导式
    print({key:666 for key in range(1, 101)})
    
    # 第四种方法
    from collections import defaultdict
    def func():
        return 666
    my_dict = defaultdict(func)
    for i in range(1, 101):
        my_dict[i]
    print(my_dict)
    # 4.Counter: 计数器,主要用来计数
    # 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})
  • 相关阅读:
    Eclipse使用之将Git项目转为Maven项目, ( 注意: 最后没有pom.xml文件的, 要转化下 )
    静态类型语言,动态类型语言的区别
    UT, FT ,E2E 测试的意思
    git tag 用法 功能作用
    java 常用异常及作用
    git checkout -b 分支name 分支的新建, 切换, 删除, 查看
    项目上有红色感叹号, 一般就是依赖包有问题, remove依赖,重新加载,maven的也行可认删除,自己也会得新加载
    密码学初级教程(五)消息认证码MAC-Message Authentication Code
    密码学初级教程(六)数字签名 Digital Signature
    密码学初级教程(四)单向散列函数-指纹-
  • 原文地址:https://www.cnblogs.com/shawnhuang/p/10244348.html
Copyright © 2011-2022 走看看