zoukankan      html  css  js  c++  java
  • 一些常用模块2

    一 json与pickle模块

      1.1 什么是序列化和反序列化

        我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化

        内存中的数据类型---->序列化---->特定的格式(json格式或者pickle格式)

        内存中的数据类型<----反序列化<----特定的格式(json格式或者pickle格式)

      1.2 为什么要有序列化

        1、可用于存储=>用于存档

        2、传输给其他平台使用=>跨平台数据交互

        强调:

        针对用途1的特定一格式:可是一种专用的格式=>pickle只有python可以识别

        针对用途2的特定一格式:应该是一种通用、能够被所有语言识别的格式=>json

      1.3 如何使用这两种模块

        序列化:

    import json
    json_res = json.dumps([1,'asfas',True,False])
    print(json_res,type(json_res))
    
    # 序列化的结果写入文件的复杂方法
    json_res = json.dumps([1,'asfas',True,False])
    with open('a.json','wt',encoding='utf-8')as f:
        f.write(json_res)
    
    # 将序列化的结果写入文件的简单方法
    with open('a.json','wt',encoding='utf-8')as f:
        json.dump([1,'asfas',True,False],f)

        反序列化

    import json
    l = json.loads(json_res)
    print(l,type(l))
    
    # 从文件读取json格式的字符串进行反序列化操作的复杂方法
    with open('a.json',mode='rt',encoding='utf-8') as f:
        json_res=f.read()
        l=json.loads(json_res)
        print(l,type(l))
    
    # 从文件读取json格式的字符串进行反序列化操作的简单方法
    with open('a.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})#集合是py独有的,json不兼容,报错
    
    #一定要搞清楚json格式,不要与python混淆
    l=json.loads("[1,1.3,true,'aaa', true, false]") #json格式的字符串是双引号,报错

        了解

    # 在python解释器2.7与3.6之后都可以json.loads(bytes类型),但唯独3.5不可以
    l = json.loads(b'[1, "aaa", true, false]')
    print(l, type(l))

         

    # 一.什么是猴子补丁?
          猴子补丁的核心就是用自己的代码替换所用模块的源代码,详细地如下
      1,这个词原来为Guerrilla Patch,杂牌军、游击队,说明这部分不是原装的,在英文里guerilla发音和gorllia(猩猩)相似,再后来就写了monkey(猴子)。
      2,还有一种解释是说由于这种方式将原来的代码弄乱了(messing with it),在英文里叫monkeying about(顽皮的),所以叫做Monkey Patch。
    
    
    # 二. 猴子补丁的功能(一切皆对象)
      1.拥有在模块运行时替换的功能, 例如: 一个函数对象赋值给另外一个函数对象(把函数原本的执行的功能给替换了)
    class Monkey:
        def hello(self):
            print('hello')
    
        def world(self):
            print('world')
    
    
    def other_func():
        print("from other_func")
    
    
    
    monkey = Monkey()
    monkey.hello = monkey.world
    monkey.hello()
    monkey.world = other_func
    monkey.world()
    
    # 三.monkey patch的应用场景
    如果我们的程序中已经基于json模块编写了大量代码了,发现有一个模块ujson比它性能更高,
    但用法一样,我们肯定不会想所有的代码都换成ujson.dumps或者ujson.loads,那我们可能
    会想到这么做
    import ujson as json,但是这么做的需要每个文件都重新导入一下,维护成本依然很高
    此时我们就可以用到猴子补丁了
    只需要在入口处加上
    , 只需要在入口加上:
    
    import json
    import ujson
    
    def monkey_patch_json():
        json.__name__ = 'ujson'
        json.dumps = ujson.dumps
        json.loads = ujson.loads
    
    monkey_patch_json() # 之所以在入口处加,是因为模块在导入一次后,后续的导入便直接引用第一次的成果
    
    #其实这种场景也比较多, 比如我们引用团队通用库里的一个模块, 又想丰富模块的功能, 除了继承之外也可以考虑用Monkey
    Patch.采用猴子补丁之后,如果发现ujson不符合预期,那也可以快速撤掉补丁。个人感觉Monkey
    Patch带了便利的同时也有搞乱源代码的风险!
    猴子补丁

         模块pickle

    #如果要从文件读取来用b模式
    import pickle
    res=pickle.dumps({1,2,3,4,5})
    print(res,type(res))
    
    s=pickle.loads(res)
    print(s,type(s))
    import pickle
    
    with open('a.pkl',mode='wb') as f:
        # 一:在python3中执行的序列化操作如何兼容python2
        # python2不支持protocol>2,默认python3中protocol=4
        # 所以在python3中dump操作应该指定protocol=2
        pickle.dump('你好啊',f,protocol=2)
    
    with open('a.pkl', mode='rb') as f:
        # 二:python2中反序列化才能正常使用
        res=pickle.load(f)
        print(res)
    py2和py3的兼容问题

    二 shelve 与xml 模块(了解)

      shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型

    import shelve
    
    f=shelve.open(r'sheve.txt')
    # f['stu1_info']={'name':'egon','age':18,'hobby':['piao','smoking','drinking']}
    # f['stu2_info']={'name':'gangdan','age':53}
    # f['school_info']={'website':'http://www.pypy.org','city':'beijing'}
    
    print(f['stu1_info']['hobby'])
    f.close()
    View Code

      xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

      xml的格式如下,就是通过<>节点来区别数据结构的:

    <?xml version="1.0"?>
    <data>
        <country name="Liechtenstein">
            <rank updated="yes">2</rank>
            <year>2008</year>
            <gdppc>141100</gdppc>
            <neighbor name="Austria" direction="E"/>
            <neighbor name="Switzerland" direction="W"/>
        </country>
        <country name="Singapore">
            <rank updated="yes">5</rank>
            <year>2011</year>
            <gdppc>59900</gdppc>
            <neighbor name="Malaysia" direction="N"/>
        </country>
        <country name="Panama">
            <rank updated="yes">69</rank>
            <year>2011</year>
            <gdppc>13600</gdppc>
            <neighbor name="Costa Rica" direction="W"/>
            <neighbor name="Colombia" direction="E"/>
        </country>
    </data>
    
    xml数据
    View Code

      xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:

    # print(root.iter('year')) #全文搜索
    # print(root.find('country')) #在root的子节点找,只找一个
    # print(root.findall('country')) #在root的子节点找,找所有
    import xml.etree.ElementTree as ET
     
    tree = ET.parse("xmltest.xml")
    root = tree.getroot()
    print(root.tag)
     
    #遍历xml文档
    for child in root:
        print('========>',child.tag,child.attrib,child.attrib['name'])
        for i in child:
            print(i.tag,i.attrib,i.text)
     
    #只遍历year 节点
    for node in root.iter('year'):
        print(node.tag,node.text)
    #---------------------------------------
    
    import xml.etree.ElementTree as ET
     
    tree = ET.parse("xmltest.xml")
    root = tree.getroot()
     
    #修改
    for node in root.iter('year'):
        new_year=int(node.text)+1
        node.text=str(new_year)
        node.set('updated','yes')
        node.set('version','1.0')
    tree.write('test.xml')
     
     
    #删除node
    for country in root.findall('country'):
       rank = int(country.find('rank').text)
       if rank > 50:
         root.remove(country)
     
    tree.write('output.xml')
    View Code
    #在country内添加(append)节点year2
    import xml.etree.ElementTree as ET
    tree = ET.parse("a.xml")
    root=tree.getroot()
    for country in root.findall('country'):
        for year in country.findall('year'):
            if int(year.text) > 2000:
                year2=ET.Element('year2')
                year2.text='新年'
                year2.attrib={'update':'yes'}
                country.append(year2) #往country节点下添加子节点
    
    tree.write('a.xml.swap')
    View Code
    import xml.etree.ElementTree as ET
     
     
    new_xml = ET.Element("namelist")
    name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
    age = ET.SubElement(name,"age",attrib={"checked":"no"})
    sex = ET.SubElement(name,"sex")
    sex.text = '33'
    name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
    age = ET.SubElement(name2,"age")
    age.text = '19'
     
    et = ET.ElementTree(new_xml) #生成文档对象
    et.write("test.xml", encoding="utf-8",xml_declaration=True)
     
    ET.dump(new_xml) #打印生成的格式
    自己创建xml文档:

    三 configparser模块

      txt.ini配置文件内容

    # 注释1
    ; 注释2
    
    [section1]
    k1 = v1
    k2:v2
    user=egon
    age=18
    is_admin=true
    salary=31
    
    [section2]
    k1 = v1

      读取操作

    import configparser
    
    config=configparser.ConfigParser()
    config.read('txt.ini')
    
    #查看所有的标题
    res=config.sections() 
    print(res)#['section1', 'section2']
    
    #查看标题section1下所有key=value的key
    options=config.options('section1')
    print(options) #['k1', 'k2', 'user', 'age', 'is_admin', 'salary']
    
    #查看标题section1下所有key=value的(key,value)格式
    item_list=config.items('section1')
    print(item_list) #[('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]
    
    #查看标题section1下user的值=>字符串格式
    val=config.get('section1','user')
    print(val) #egon
    
    #查看标题section1下age的值=>整数格式
    val1=config.getint('section1','age')
    print(val1) #18
    
    #查看标题section1下is_admin的值=>布尔值格式
    val2=config.getboolean('section1','is_admin')
    print(val2) #True
    
    #查看标题section1下salary的值=>浮点型格式
    val3=config.getfloat('section1','salary')
    print(val3) #31.0

      

     四  hashlib模块

      4.1 什么是hash

        hash一类算法,该算法接受传入的内容,经过运算得到一串hash值

        hash值的特点:

          1 只要传入的内容一样,得到的hash值必然一样

          2 不能由hash值返解成内容

          3 不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度是一定

      4.2 hash的用途

        用途1:特点2用于密码密文传输与验证

        用途2:特点1,3用于文件完整性校验

      4.3 如何使用hash

    import hashlib
    # md5可以换成其他的加密方式
    m=hashlib.md5()
    m.update('hello'.encode('utf-8'))
    m.update('world'.encode('utf-8'))
    res=m.hexdigest() # 'helloworld'
    print(res)
    
    # 验证特点1
    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)

        大文件快速进行比对效验

    # 文件过大要进行比对会很慢:我们可以通过指针的随机选取位置来进行效验,这样就加快了速度
    import hashlib
    m=hashlib.md5()
    f=open('a.txt',mode='rb')
    f.seek()
    f.read(2000)
    m.update(文件的一行)
    m.hexdigest()

        模拟撞库

    cryptograph='aee949757a2e698417463d47acac93df'
    import hashlib
    # 制作密码字段
    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

        提升撞库的成本——>密码加盐:防止撞库的成功率

    import hashlib
    m=hashlib.md5()
    m.update('天王'.encode('utf-8'))
    m.update('alex3714'.encode('utf-8'))
    m.update('盖地虎'.encode('utf-8'))
    print(m.hexdigest())

    五 suprocess模块

    
    
    import subprocess
    #就是运行命令 把运行结果放到管道中
    obj=subprocess.Popen('echo 123 ; ls / ; ls /root',shell=True,#shell就是打开cmd
    stdout=subprocess.PIPE, #正确管道
    stderr=subprocess.PIPE, #错误管道
    )

    print(obj)
    res=obj.stdout.read()
    print(res.decode('utf-8'))

    err_res=obj.stderr.read()
    print(err_res.decode('utf-8'))
     
  • 相关阅读:
    error :expected initializer before
    数字转字符
    转载转载转载指针占几个字节
    转载转载转载
    二维数组1
    响应式布局
    flex布局
    wepy踩坑经历
    css命名规范(转载)
    28.设计模式
  • 原文地址:https://www.cnblogs.com/bk134/p/12606274.html
Copyright © 2011-2022 走看看