zoukankan      html  css  js  c++  java
  • Python全栈开发记录_第八篇(模块收尾工作 json & pickle & shelve & xml)

      由于上一篇篇幅较大,留下的这一点内容就想在这里说一下,顺便有个小练习给大家一起玩玩,首先来学习json 和 pickle。

      之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。

    什么是序列化?

    我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

    序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

    反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

    JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

    • json,用于字符串 和 python数据类型间进行转换
    • pickle,用于python特有的类型 和 python的数据类型间进行转换(比如函数、类之类的)
    # -*- coding:utf-8 -*-
    # -----------------------json序列化----------------
    import json
    dict1 = {"name": "liu", "age": 18, "sex": "man"}
    
    j_dict = json.dumps(dict1)   # 转成str格式
    f = open("json_dumps_text", "w")
    f.write(j_dict)     # 等价于json.dump(dict1, f),dump就是帮你转成str然后帮你写入
    f.close()
    
    # -----------------------json反序列化----------------
    import json
    f = open("json_dumps_text", "r")
    res = json.loads(f.read())      # 等价于json.load(f),loads就是将读出来的str转化成原本的格式,而load就是将文件句柄内的全部读出来然后转换格式
    print(res)
    # -*- coding:utf-8 -*-
    # -----------------------pickle序列化----------------
    import pickle
    
    dict1 = {"name": "liu", "age": 18, "sex": "man"}
    p_dict = pickle.dumps(dict1)
    print(type(p_dict))     # <class 'bytes'>,这里是将str转换成bytes类型
    print(p_dict)
    
    f = open("pickle_text", "wb")   # 注意是w是写入str,wb是写入bytess'
    f.write(p_dict)     # 等价于pickle.dump(dict1, f)
    f.close()
    
    # -----------------------pickle反序列化----------------
    import pickle
    f = open("pickle_text", "rb")
    data = pickle.loads(f.read())   # 等价于data=pickle.load(f)
    print(data['name'])

       shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式。

    #  shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型
    import shelve
    
    f = shelve.open("shelve_text")
    # f['info'] = {"name": "liu", "age": 18, "sex": "man"}      # 将info这个key还有value写入文件
    # f.close()
    
    print(f['info'])    # 从文件内取key为info的值
    print(f.get('info')['name'])    # 从文件内取key为info下name的值

       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>

      Python操作xml,如下:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    # Author: Xiaobai Lei
    
    import xml.etree.ElementTree as ET
    
    tree = ET.parse("xml_test")     # 解析xml文件
    root = tree.getroot()       # 得到根
    print(root.tag)     # 打印根的标签--->也就是data
    
    # 遍历xml文档
    for child in root:
        print(child.tag, child.attrib)  # 打印第一级标签和属性,就是三个country和属性,其中一个就是country {'name': 'Liechtenstein'}
        for i in child:                 # 打印第二级标签和文本
            print(i.tag, i.text)
    
    # 只遍历第二级的内容,比如year
    for child in root.iter("year"):
        print(child.tag, child.text)        # 遍历出了三个year标签和文本
    
    # 修改xml内容
    for child in root.iter("year"):
        new_year = int(child.text) + 1      # 将读取出来的年份加1
        child.text = str(new_year)          # 赋值给标签文本
        child.set("test", "hello")         # 设置当前标签属性为test=hello
    
    tree.write("xml_test.xml")          # 将修改后的写入文件
    
    # 删除xml内容
    for country in root.findall('country'):     # 找到所有country标签
        rank = int(country.find('rank').text)   # 找到counry标签下的rand标签文本
        if rank > 50:                           # 如果rank大于50则移除该country标签
            root.remove(country)
    tree.write('xml_text1.xml')                 # 将删除后的结果写入文件

      自己创建xml

    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文件如下:
    
    <?xml version='1.0' encoding='utf-8'?>
    <namelist>
        <name enrolled="yes">
            <age checked="no" />
            <sex>33</sex>
        </name>
        <name enrolled="no">
            <age>19</age>
        </name>
    </namelist>

    小练习:

    模拟实现一个ATM + 购物商城程序
    
    1、信用卡额度 15000或自定义
    2、实现购物商城,买东西加入 购物车,调用信用卡接口结账
    3、信用卡可以提现,手续费5%
    4、支持多账户登录
    5、支持账户间转账
    6、记录每月日常消费流水
    7、提供还款接口
    8、ATM记录操作日志 
    9、提供管理接口,包括添加账户、用户额度,冻结账户等。。。
    10、用户认证用装饰器

     代码有点多,我就把代码放在了github上,地址如下(建议主要参考整个目录结构):

    https://github.com/leixiaobai/python_project.git
  • 相关阅读:
    http和socket之长连接和短连接区别【转】
    Linux下内存泄漏工具【转】
    arm交叉编译器gnueabi、none-eabi、arm-eabi、gnueabihf等的区别【转】
    C语言字节对齐 __align(),__attribute((aligned (n))),#pragma pack(n)【转】
    简单解读linux的/proc下的statm、maps、memmap 内存信息文件分析【转】
    linux调试工具glibc的演示分析-core dump double free【转】
    Linux信号(signal)机制【转】
    细说JavaScript对象(4): for in 循环
    细说JavaScript对象(3):hasOwnProperty
    细说JavaScript对象(2):原型对象
  • 原文地址:https://www.cnblogs.com/leixiaobai/p/10017544.html
Copyright © 2011-2022 走看看