python学习day20 序列化模块 模块的导入

http://www.cnblogs.com/Eva-J/articles/7228075.html#_label9

序列化模块

为什么要序列化?

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

从数据类型 --> 字符串的过程 序列化
从字符串 --> 数据类型的过程 反序列化

 

json --通用的序列化格式

通用的序列化格式
只有很少的一部分数据类型能够通过json转化成字符串
dump 和文件有关
不能load多次

pickle

所有的python中的数据类型都可以转化成字符串形式
pickle序列化的内容只有python能理解
且部分反序列化依赖python代码
dump和load的时候,文件是rb或者wb打开的

shelve

比较新
序列化句柄
使用句柄直接操作,非常方便

json

数字 字符串 列表 字典 元组

dumps -- 序列化

loads --- 反序列化

直接在内存中执行

import json

dic = {1:"a",2:'b'}
print(type(dic),dic)

str_d = json.dumps(dic)   # 序列化
print(type(str_d),str_d)  # str {"k": "v1"} 双引号
# '{"kkk":"v"}'
dic_d = json.loads(str_d) # 反序列化
print(type(dic_d),dic_d)

# 元组序列化后变成列表字符化,反序列化后还是列表
# 集合不能序列化

dump load

可以写入文件

import json
f = open('json_file','w')
dic = {'k1':'v1','k2':'v2','k3':'v3'}
json.dump(dic,f)  #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
f.close()

f = open('json_file')
dic2 = json.load(f)  #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
f.close()
print(type(dic2),dic2)

 

import json
f = open('file','w')
json.dump({'国籍':'中国'},f)
ret = json.dumps({'国籍':'中国'})
f.write(ret+'\n')
json.dump({'国籍':'美国'},f,ensure_ascii=False) # json中的是汉字 不加的话会是bytes编码
ret = json.dumps({'国籍':'美国'},ensure_ascii=False)
f.write(ret+'\n')
f.close()

格式化输出:

 

import json
data = {'username':['李华','二愣子'],'sex':'male','age':16}
json_dic2 = json.dumps(data,sort_keys=True,indent=2,separators=(',',':'),ensure_ascii=False)
print(json_dic2)

# Skipkeys:默认值是False,如果dict的keys内的数据不是python的基本类型(str,unicode,int,long,float,bool,None),设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key 
# ensure_ascii:,当它为True的时候,所有非ASCII码字符显示为\uXXXX序列,只需在dump时将ensure_ascii设置为False即可,此时存入json的中文即可正常显示。) indent:应该是一个非负的整型,如果是0就是顶格分行显示,如果为空就是一行最紧凑显示,否则会换行且按照indent的数值显示前面的空白分行显示,这样打印出来的json数据也叫pretty-printed json 
# separators:分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(‘,’,’:’);这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开。 
# sort_keys:将数据根据keys的值进行排序。 

 

模块

模块导入顺序:

内置模块
扩展模块 比如django
自定义模块


模块级别函数定义的执行将函数名放入模块全局名称空间表,用globals()可以查看

为了防止重复导入,python的优化手段是:第一次导入后就将模块名加载到内存了,后续的import语句仅是对已经加载大内存中的模块对象增加了一次引用,不会重新执行模块内的语句。

定义一个模块:

#my_module.py
print('from the my_module.py')

money=1000

def read1():
    print('my_module->read1->money',money)

def read2():
    print('my_module->read2 calling read1')
    read1()

def change():
    global money
    money=0

 

我们可以从sys.modules中找到当前已经加载的模块,sys.modules是一个字典,内部包含模块名与模块对象的映射,该字典决定了导入模块时是否需要重新导入。

先从sys.modules里查看是否已经被导入
如果没有被导入,就依据sys.path路径取寻找模块
找到了就导入
创建这个模块的命名空间
执行文件,把文件中的名字都放到命名空间里

#demo.py
import my_module #只在第一次导入时才执行my_module.py内代码,此处的显式效果是只打印一次'from the my_module.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.
import my_module
import my_module
import my_module

'''
执行结果:
from the my_module.py
'''

每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样我们在编写自己的模块时,就不用担心我们定义在自己模块中全局变量会在被导入时,与使用者的全局变量冲突

  • 使用import demo导入模块,会创建一个独立的命名空间,里面的所有函数都被导入进来,再定义一个和demo中函数名一样的函数,就无效
  • 使用from...import...导入,再定义一个和demo中函数名一样的函数,导入的函数就被覆盖

from my_module import * 把my_module中所有的不是以下划线(_)开头的名字都导入到当前位置,大部分情况下我们的python程序不应该使用这种导入方式,因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字。而且可读性极其的差,在交互式环境中导入时没有问题。

 

在my_module.py中新增一行,__all__只和from...import* 关联

__all__=['money','read1'] #这样在另外一个文件中用from my_module import *就这能导入列表中规定的两个名字

 import...

import
# 1 
import 模块名
    模块名.变量名 和本文件中的变量名完全不冲突
# 2 import...as..
import 模块名 as 重命名的模块名 : 提高代码的兼容性
# 3 导入多个模块
import 模块1,模块2

from...import...

from import
# 1
from 模块名 import 变量名
# 直接使用 变量名 就可以完成操作
# 如果本文件中有相同的变量名会发生冲突

# 2
from 模块名 import 变量名字 as 重命名变量名

# 3
from 模块名 import 变量名1,变量名2

# 4
from 模块名 import *
# 将模块中的所有变量名都放到内存中
# 如果本文件中有相同的变量名会发生冲突

# 5
from 模块名 import * 和 __all__ 是一对
# 没有这个变量,就会导入所有的名字
# 如果有all 只导入all列表中的名字

重要! 把模块当脚本运行

我们可以通过模块的全局变量__name__来查看模块名:

在模块中 有一个变量__name__,
当我们直接执行这个模块的时候,这个模块中__name__ == '__main__'
当我们执在其他模块中引用这个模块的时候,这个模块中的__name__ == '模块的名字',if __name__ =='__main__'下的内容不会执行

if __name__ =='__main__':

 

为了提高加载模块的速度,强调强调强调:提高的是加载速度而绝非运行速度。python解释器会在__pycache__目录中下缓存每个模块编译后的版本,格式为:module.version.pyc。通常会包含python的版本号。例如,在CPython3.3版本下,my_module.py模块会被缓存成__pycache__/my_module.cpython-33.pyc。这种命名规范保证了编译后的结果多版本共存。

posted @ 2018-11-08 21:06  xyfun72  阅读(173)  评论(0编辑  收藏  举报