首页 > 其他 > 详细

018_序列化模块_什么是模块

时间:2019-03-15 19:41:15      阅读:192      评论:0      收藏:0      [点我收藏+]
1,序列化模块
  什么叫序列化——将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化。
  比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给?现在我们能想到的方法就是存在文件里,然后另一个python程序再从文件里读出来。但是我们都知道,对于文件来说是没有字典这个概念的,所以我们只能将数据转换成字典放到文件中。你一定会问,将字典转换成一个字符串很简单,就是str(dic)就可以办到了,为什么我们还要学习序列化模块呢?没错序列化的过程就是从dic 变成str(dic)的过程。现在你可以通过str(dic),将一个名为dic的字典转换成一个字符串,但是你要怎么把一个字符串转换成字典呢?
  聪明的你肯定想到了eval(),如果我们将一个字符串类型的字典str_dic传给eval,就会得到一个返回的字典类型了。eval()函数十分强大,但是eval是做什么的?e官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。BUT!强大的函数有代价。安全性是其最大的缺点。想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句,那么后果实在不堪设设想。而使用eval就要担这个风险。所以,我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构)
 

2,什么时候使用序列化

  • 数据存储
  • 网络上传输的时候

3,三个块
  • json
  • pickle
  • shelve
4
  • json  # 数字 字符串 列表 字典 元组
     通用的序列化格式
       只有很少的一部分数据类型能够通过json转化成字符串
  • pickle
        所有的python中的数据类型都可以转化成字符串形式
        pickle序列化的内容只有python能理解
        且部分反序列化依赖python代码
  • shelve
        序列化句柄
        使用句柄直接操作,非常方便

5
  5.1,json
   dumps序列化方法  loads反序列化方法  直接对内存中的数据进行操作,操作后还在内存里
dic = {"k1":‘v1‘}
print(type(dic),dic)
import json
str_d = json.dumps(dic)     #序列化    #>>>
print(type(str_d),str_d)
dic_d = json.loads(str_d)   #反序列化   #>>>
print(type(dic_d),dic_d)
  5.2,json
    dump    load 对文件进行操作的
import json
dic = {1:"a",2:‘b‘}
f = open(‘fff‘,‘w‘,encoding=‘utf-8‘)
json.dump(dic,f)
f.close()
f = open(‘fff‘)
res = json.load(f)
f.close()
print(type(res),res)
  5.3,在文件中写入中文序列化
import json
dic = {1:"中国",2:‘b‘}
f = open(‘fff‘,‘w‘,encoding=‘utf-8‘)
json.dump(dic,f,ensure_ascii=False)   #要加入ensure_ascii=False,不然会写入bytes类型
f.close()
f = open(‘fff‘,encoding=‘utf-8‘)
res = json.load(f)
f.close()
print(type(res),res)

  5.4(好像不能这样写)

# import json
# json dump load
# dic = {1:"中国",2:‘b‘}
# f = open(‘fff‘,‘w‘,encoding=‘utf-8‘)
# json.dump(dic,f,ensure_ascii=False)
# json.dump(dic,f,ensure_ascii=False)
# f.close()
# f = open(‘fff‘,encoding=‘utf-8‘)
# res1 = json.load(f)
# res2 = json.load(f)
# f.close()
# print(type(res1),res1)
# print(type(res2),res2)

  5.4,分次往里写,分次往外读

# json
# dumps {} -- >为了分次写将其写入成一行一行的dumps ‘{}\n‘
# 一行一行的读
# ‘{}\n‘
# ‘{}‘ loads

l = [{‘k‘:‘111‘},{‘k2‘:‘111‘},{‘k3‘:‘111‘}]
f = open(‘file‘,‘w‘)
import json
for dic in l:
    str_dic = json.dumps(dic)
    f.write(str_dic+‘\n‘)
f.close()
f = open(‘file‘)
import json
l = []
for line in f:
    dic = json.loads(line.strip())
    l.append(dic)
f.close() 
print(l)
6,pickle
# 用pickle dump的序列化是bytes类型的
##
这时候机智的你又要说了,既然pickle如此强大,为什么还要学json呢?
这里我们要说明一下,json是一种所有的语言都可以识别的数据结构。
如果我们将一个字典或者序列化成了一个json存在文件里,那么java代码或者js代码也可以拿来用。
但是如果我们用pickle进行序列化,其他语言就不能读懂这是什么了~
所以,如果你序列化的内容是列表或者字典,我们非常推荐你使用json模块
但如果出于某种原因你不得不序列化其他的数据类型,而未来你还会用python对这个数据进行反序列化的话,那么就可以使用pickle
 
6.1,
import pickle
dic = {‘k1‘:‘v1‘,‘k2‘:‘v2‘,‘k3‘:‘v3‘}
str_dic = pickle.dumps(dic)
print(str_dic)  #一串二进制内容
dic2 = pickle.loads(str_dic)
print(dic2)    #字典
6.2,
(下面的程序,好像只有pickle能这样写,json不能。不确定)
# pickle支持分次load,json不支持直接load
# pickle与与文件打交道时,文件的模式要加b,即文件模式要是bytes数据类型的
import time
struct_time1  = time.localtime(1000000000)
struct_time2  = time.localtime(2000000000)
f = open(‘pickle_file‘,‘wb‘)
pickle.dump(struct_time1,f)
pickle.dump(struct_time2,f)
f.close()
f = open(‘pickle_file‘,‘rb‘)
struct_time1 = pickle.load(f)
struct_time2 = pickle.load(f)
print(struct_time1.tm_year)
print(struct_time2.tm_year)
f.close()
7, shelve
  #使用时会创建三个文件
7.1,
import shelve
f = shelve.open(‘shelve_file‘)
f[‘key‘] = {‘int‘:10, ‘float‘:9.5, ‘string‘:‘Sample data‘}  #直接对文件句柄操作,就可以存入数据
f.close()
import shelve
f1 = shelve.open(‘shelve_file‘)
existing = f1[‘key‘]  #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
f1.close()
print(existing)
7.2,由于shelve在默认情况下时不会记录任何修改的,
     所以我们在sheleve.open()时候需要修改默认参数writeback=True才会保存修改。
     否则对象的修改是不会保存的。
import shelve
#修改不会保存
f1 = shelve.open(‘shelve_file‘)
print(f1[‘key‘])
f1[‘key‘][‘new_value‘] = ‘this was not here before‘
f1.close()
#修改会保存
f2 = shelve.open(‘shelve_file‘, writeback=True)
print(f2[‘key‘])
f2[‘key‘][‘new_value‘] = ‘this was not here before‘
f2.close()
 
8,模块
   什么是模块?
     常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀。
     但其实import加载的模块分为四个通用类别: 
    1 使用python编写的代码(.py文件)
    2 已被编译为共享库或DLL的C或C++扩展
    3 包好一组模块的包
    4 使用C编写并链接到python解释器的内置模块
8.1,
   自己写的程序文件,可以在另一个程序文件中通过“import 文件名”导入。导入时就执行了被导入的程序文件,写多次导入也是只执行一次。
   要调用被导入程序文件中的函数,要通过“模块名.函数名”执行。
import demo
def read():
    print(‘my read func‘)
demo.read()
print(demo.money)
8.2,导入过程
    先从sys.modules里查看是否已经被导入如果没有被导入,就依据sys.path路径取寻找模块,找到了就导入
    创建这个模块的命名空间
    执行文件,把文件中的名字都放到命名空间里
import sys
print(sys.modules.keys())
print(sys.path)
8.3,给模块起别名
import time as t   #将time模块命名为t
print(t.time())
  其别名的作用:
     导入的不同模块,如有相同的方法,可以将两个模块命名成同样的别名。
oracle
mysql
if 数据库 == ‘oracle’:
    import oracle as db
elif 数据库 == ‘mysql’:
    import mysql as db
#两个数据图库都有 connect方法
#就都可以用 db.connect 调用
#想要操作数据库就要:
# 连接数据库   db.connect
# 登录认证
# 增删改查
# 关闭数据库
8.4,导入模块要在程序文件前导入,为了方便查看使用了什么模块,
     导入顺序:内置的,扩展的,自定义的
8.5,导入模块中的某个具体的方法,用
from time import sleep
8.5.1,不同于导入整个模块,单独导入一个模块中的方法时,导入的方法的名字就属于本程序文件全局变量名的范围了。因此,如果再定义一个和导入的方法一样的变量名时,导入的就会被覆盖。
from demo import read
def read():
    print(‘my read‘)
read()
8.5.2,可以使用from demo import * 导入所有方法。
  • 但要注意:当被导入模块中,前面用“__all__ = [‘变量名‘,‘方法名’]”则只能导入限定的这几个;
  • 不同于“import 模块”本程序不会对其有影响,而这种方法导入,即使将将其变量名,方法名归入本程序全局空间中
9,__name__
       # 在模块中 有一个变量__name__,
       # 当我们直接执行这个模块的时候,__name__ == ‘__main__‘
      # 当我们执行其他模块,在其他模块中引用这个模块的时候,这个模块中的__name__ == ‘模块的名字‘
if __name__ == ‘__main__‘
   pass
    #如果在本在这句话所在的程序中执行程序,该程序会执行pass
    #如果该模块被导入到其他模块,当等于被导入模块名时才执行
    if __name__ == ‘__被导入模块名__‘
 

 

018_序列化模块_什么是模块

原文:https://www.cnblogs.com/eternity-twinkle/p/10538923.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!