zoukankan      html  css  js  c++  java
  • day23-json、pickle、configparser、hashlib、suprocess模块

    json&pickle模块

    
    1、什么是序列化 & 反序列化
      内存中的数据类型--- -> 序列化--- -> 特定的格式(json格式或者pickle格式)
       内存中的数据类型 < ----反序列化 < ----特定的格式(json格式或者pickle格式)
    
        土办法:
        {'aaa': 111}-- -> 序列化str({'aaa': 111})---- -> "{'aaa':111}"
        {'aaa': 111} < ---反序列化eval("{'aaa':111}") < -----"{'aaa':111}"
    
    2、为何要序列化
    序列化得到结果 = >特定的格式的内容有两种用途
     1、可用于存储 =》用于存档
      2、传输给其他平台使用 =》跨平台数据交互
       python                 java
          列表     特定的格式      数组
    
        强调:
        针对用途1的特定一格式:可是一种专用的格式 =》pickle只有python可以识别
        针对用途2的特定一格式:应该是一种通用、能够被所有语言识别的格式 =》json
    
    import pickle
    import ujson as json  # 不行
    import ujson
    import json
    3、如何序列化与反序列化
    示范1
    # 序列化
    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])
    # print(json_res,type(json_res)) # "[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))
    
    
    json验证: json格式兼容的是所有语言通用的数据类型,不能识别某一语言的所独有的类型
    json.dumps({1, 2, 3, 4, 5})
    
    json强调:一定要搞清楚json格式,不要与python混淆
    l = json.loads('[1, "aaa", true, false]')
    l = json.loads("[1,1.3,true,'aaa', true, false]")
    print(l[0])
    
    了解
    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))
    
    4、猴子补丁
    在入口处打猴子补丁
    
    
    def monkey_patch_json():
        json.__name__ = 'ujson'
        json.dumps = ujson.dumps
        json.loads = ujson.loads
    
    
    monkey_patch_json()  # 在入口文件出运行
    
    
    后续代码中的应用
    json.dumps()
    json.dumps()
    json.dumps()
    json.dumps()
    json.dumps()
    json.dumps()
    json.dumps()
    json.dumps()
    json.loads()
    json.loads()
    json.loads()
    json.loads()
    json.loads()
    json.loads()
    json.loads()
    json.loads()
    json.loads()
    json.loads()
    json.loads()
    
    
    5.pickle模块
    res = pickle.dumps({1, 2, 3, 4, 5})
    print(res, type(res))
    
    s = pickle.loads(res)
    print(s, type(s))
    

    configparser模块

    一、ConfigParser简介
    ConfigParser 是用来读取配置文件的包。配置文件的格式如下:中括号“[ ]”内包含的为section。section 下面为类似于key-value 的配置内容。
    
    [db]
    db_host = 127.0.0.1
    db_port = 69
    db_user = root
    db_pass = root
    host_port = 69
    
    [concurrent]
    thread = 10
    processor = 20
    括号“[ ]”内包含的为section。紧接着section 为类似于key-value 的options 的配置内容。
    
    
    
    
    二、ConfigParser 初始化对象
    使用ConfigParser 首选需要初始化实例,并读取配置文件:
    import configparser
    config = configparser.ConfigParser()
    config.read("ini", encoding="utf-8")
    三、ConfigParser 常用方法
    
    1、获取所用的section节点
    
    
    # 获取所用的section节点
    import configparser
    config = configparser.ConfigParser()
    config.read("ini", encoding="utf-8")
    print(config.sections())
    #运行结果
    # ['db', 'concurrent']
    
    2、获取指定section 的options。即将配置文件某个section 内key 读取到列表中:
    
    
    import configparser
    config = configparser.ConfigParser()
    config.read("ini", encoding="utf-8")
    r = config.options("db")
    print(r)
    #运行结果
    # ['db_host', 'db_port', 'db_user', 'db_pass', 'host_port']
    
    3、获取指点section下指点option的值
    
    
    import configparser
    config = configparser.ConfigParser()
    config.read("ini", encoding="utf-8")
    r = config.get("db", "db_host")
    # r1 = config.getint("db", "k1") #将获取到值转换为int型
    # r2 = config.getboolean("db", "k2" ) #将获取到值转换为bool型
    # r3 = config.getfloat("db", "k3" ) #将获取到值转换为浮点型
    print(r)
    #运行结果
    # 127.0.0.1
    
    4、获取指点section的所用配置信息
    
    
    import configparser
    config = configparser.ConfigParser()
    config.read("ini", encoding="utf-8")
    r = config.items("db")
    print(r)
    #运行结果
    #[('db_host', '127.0.0.1'), ('db_port', '69'), ('db_user', 'root'), ('db_pass', 'root'), ('host_port', '69')]
    
    
    5、修改某个option的值,如果不存在则会出创建
    
    
    # 修改某个option的值,如果不存在该option 则会创建
    import configparser
    config = configparser.ConfigParser()
    config.read("ini", encoding="utf-8")
    config.set("db", "db_port", "69")  #修改db_port的值为69
    config.write(open("ini", "w"))
    
    
     运行结果
    6、检查section或option是否存在,boolimport configparser
    config = configparser.ConfigParser()
    config.has_section("section") #是否存在该section
    config.has_option("section", "option")  #是否存在该option
    7、添加section 和 option
    
    
    import configparser
    config = configparser.ConfigParser()
    config.read("ini", encoding="utf-8")
    if not config.has_section("default"):  # 检查是否存在section
        config.add_section("default")
    if not config.has_option("default", "db_host"):  # 检查是否存在该option
        config.set("default", "db_host", "1.1.1.1")
    config.write(open("ini", "w"))
    
    
     运行结果
    8、删除section 和 option
    
    import configparser
    config = configparser.ConfigParser()
    config.read("ini", encoding="utf-8")
    config.remove_section("default") #整个section下的所有内容都将删除
    config.write(open("ini", "w"))
     运行结果
    9、写入文件
    
    以下的几行代码只是将文件内容读取到内存中,进过一系列操作之后必须写回文件,才能生效。
    
    import configparser
    config = configparser.ConfigParser()
    config.read("ini", encoding="utf-8")
    写回文件的方式如下:(使用configparser的write方法)
    
    config.write(open("ini", "w"))
    

    hashlib模块

    1、什么是哈希hash
    	hash一类算法,该算法接受传入的内容,经过运算得到一串hashhash值的特点:
    	I 只要传入的内容一样,得到的hash值必然一样
    	II 不能由hash值返解成内容
    	III 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是一定
    
    2hash的用途
    	用途1:特点II用于密码密文传输与验证
    	用途2:特点I、III用于文件完整性校验
    
    3、如何用
    
    	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)
    
    
    模拟撞库
    cryptograph = 'aee949757a2e698417463d47acac93df'
    
    # 制作密码字段
    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
    
    
    提升撞库的成本 = >密码加盐
    
    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()
    

    suprocess模块

    subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。
    
    使用 subprocess 模块
    subprocess 模块首先推荐使用的是它的 run 方法,更高级的用法可以直接使用 Popen 接口。
    
    run 方法语法格式如下:
    
    subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
    args:表示要执行的命令。必须是一个字符串,字符串参数列表。
    stdin、stdout 和 stderr:子进程的标准输入、输出和错误。其值可以是 subprocess.PIPE、subprocess.DEVNULL、一个已经存在的文件描述符、已经打开的文件对象或者 None。subprocess.PIPE 表示为子进程创建新的管道。subprocess.DEVNULL 表示使用 os.devnull。默认使用的是 None,表示什么都不做。另外,stderr 可以合并到 stdout 里一起输出。
    timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出 TimeoutExpired 异常。
    check:如果该参数设置为 True,并且进程退出状态码不是 0,则弹 出 CalledProcessError 异常。
    encoding: 如果指定了该参数,则 stdin、stdout 和 stderr 可以接收字符串数据,并以该编码方式编码。否则只接收 bytes 类型的数据。
    shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。
    run 方法调用方式返回 CompletedProcess 实例,和直接 Popen 差不多,实现是一样的,实际也是调用 Popen,与 Popen 构造函数大致相同,例如:
    
    实例
    #执行ls -l /dev/null 命令
    >>> subprocess.run(["ls", "-l", "/dev/null"])
    crw-rw-rw-  1 root  wheel    3,   2  5  4 13:34 /dev/null
    CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0)
    returncode: 执行完子进程状态,通常返回状态为0则表明它已经运行完毕,若值为负值 "-N",表明子进程被终。
    
    简单实例:
    
    实例
    import subprocess
    def runcmd(command):
        ret = subprocess.run(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8",timeout=1)
        if ret.returncode == 0:
            print("success:",ret)
        else:
            print("error:",ret)
    
    
    runcmd(["dir","/b"])#序列参数
    runcmd("exit 1")#字符串参数
    输出结果如下:
    
    success: CompletedProcess(args=['dir', '/b'], returncode=0, stdout='test.py
    ', stderr='')
    error: CompletedProcess(args='exit 1', returncode=1, stdout='', stderr='')
    Popen() 方法
    Popen 是 subprocess的核心,子进程的创建和管理都靠它处理。
    
    构造函数:
    
    class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, 
    preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=False, 
    startupinfo=None, creationflags=0,restore_signals=True, start_new_session=False, pass_fds=(),
    *, encoding=None, errors=None)
    常用参数:
    
    args:shell命令,可以是字符串或者序列类型(如:list,元组)
    bufsize:缓冲区大小。当创建标准流的管道对象时使用,默认-1。
    0:不使用缓冲区
    1:表示行缓冲,仅当universal_newlines=True时可用,也就是文本模式
    正数:表示缓冲区大小
    负数:表示使用系统默认的缓冲区大小。
    stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
    preexec_fn:只在 Unix 平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
    shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。
    cwd:用于设置子进程的当前目录。
    env:用于指定子进程的环境变量。如果 env = None,子进程的环境变量将从父进程中继承。
    创建一个子进程,然后执行一个简单的命令:
    
    实例
    >>> import subprocess
    >>> p = subprocess.Popen('ls -l', shell=True)
    >>> total 164
    -rw-r--r--  1 root root   133 Jul  4 16:25 admin-openrc.sh
    -rw-r--r--  1 root root   268 Jul 10 15:55 admin-openrc-v3.sh
    ...
    >>> p.returncode
    >>> p.wait()
    0
    >>> p.returncode
    这里也可以使用 p = subprocess.Popen(['ls', '-cl']) 来创建子进程。
    
    Popen 对象方法
    poll(): 检查进程是否终止,如果终止返回 returncode,否则返回 None。
    wait(timeout): 等待子进程终止。
    communicate(input,timeout): 和子进程交互,发送和读取数据。
    send_signal(singnal): 发送信号到子进程 。
    terminate(): 停止子进程,也就是发送SIGTERM信号到子进程。
    kill(): 杀死子进程。发送 SIGKILL 信号到子进程。
    实例
    import time
    import subprocess
    
    def cmd(command):
        subp = subprocess.Popen(command,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,encoding="utf-8")
        subp.wait(2)
        if subp.poll() == 0:
            print(subp.communicate()[1])
        else:
            print("失败")
    
    
    
    cmd("java -version")
    cmd("exit 1")
    输出结果如下:
    
    java version "1.8.0_31"
    Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
    Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)
    
    失败
    

    作业

    1、把登录与注册的密码都换成密文形式
    2、文件完整性校验(考虑大文件)
    3、注册功能改用json实现
    4、项目的配置文件采用configparser进行解析
    
  • 相关阅读:
    201521123105 第8周Java学习总结
    201521123105 第七周Java学习总结
    201521123105 第六周Java学习总结
    201521123105 第四周Java学习总结
    201521123105 第三周Java学习总结
    201521123105《jave程序》第二周学习总结
    201521123105 《Java程序设计》第1周学习总结
    网络15软工个人作业5——软件工程总结
    个人作业4——alpha阶段个人总结
    软件工程网络15个人作业3——案例分析
  • 原文地址:https://www.cnblogs.com/zdw20191029/p/14553349.html
Copyright © 2011-2022 走看看