一,体系化模块

什么样叫种类化——将本来的字典、列表等情节转换到三个字符串的长河就称为序列化

json 1json 2

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

缘何要拓展体系化

种类化的目标

壹 、以某种存储格局使自定义对象持久性;

② 、将目的从二个地点传递到另二个地点。

三 、使程序更具维护性。

json 3

 

1,json模块

Json模块提供了多少个职能:dumps、dump、loads、load

1)dumps和loads

json 4json 5

#json dumps序列化方法 loads反序列化方法
dic = {1:"a",2:'b'}
print(type(dic),dic)
import json
str_d = json.dumps(dic)   # 序列化
print(type(str_d),str_d)
# '{"kkk":"v"}'#注意:kkk用" "(双引号引起来了)
dic_d = json.loads(str_d) # 反序列化
print(type(dic_d),dic_d)
'''
<class 'dict'> {1: 'a', 2: 'b'}
<class 'str'> {"1": "a", "2": "b"}
<class 'dict'> {'1': 'a', '2': 'b'}
'''

dumps和loads

dumps是体系化方法,loads反连串化方法

2)dump与load

json 6json 7

import json
# json dump load
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)
'''
<class 'dict'> {'2': 'b', '1': 'a'}
'''

dump和load

3)dumps、loads与dump、load的区别

有s的直白在内存操作数据类型,没有s的方法是直接在文件里读写数据类型。 

dump须求需要有文件句柄,load无法举办反复load。

4)ensure_ascii关键字参数

json 8json 9

import json
f = open('file','w')
json.dump({'国籍':'中国'},f)
ret = json.dumps({'国籍':'中国'})
f.write(ret+'\n')
json.dump({'国籍':'美国'},f,ensure_ascii=False)
ret = json.dumps({'国籍':'美国'},ensure_ascii=False)
f.write(ret+'\n')
f.close()

ensure_ascii关键字参数

5)json格式化输出

json 10json 11

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)

json格式化输出

2,pickle

    #不无的python中的数据类型都得以转化成字符串方式

    #pickle系列化的内容唯有python能了解

    #且部分反体系化依赖python代码

    #可以分步dump和分步load

 #系列化与反体系话要求一致的条件

pickle模块提供了多个效益:dumps、dump、loads、load

1)pickle 的dumps和loads

import pickle
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = pickle.dumps(dic)
print(str_dic)  #一串二进制内容

dic2 = pickle.loads(str_dic)
print(dic2)    #字典

2)分步dump与load

dump和load必须用wb和rb打开

json 12json 13

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()

分步dump和分步load

3,shelve

    #序列化句柄

    #动用句柄直接操作,分外便利

shelve也是python提要求大家的种类化工具,比pickle用起来更简雅培些

shelve只提须求大家三个open方法,open方法获得一个文本句柄,操作和字典类似。是用key来访问的,使用起来和字典类似。

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)

二、模块

1,什么是模块?

壹个模块就是三个含有了python定义和阐明的文书,文件名就是模块名字加上.py的后缀。

2,import加载的模块分为八个通用项目:

  1 用到python编写的代码(.py文件)

  2 已被编译为共享库或DLL的C或C++扩张

  3 包好一组模块的包

  4 采用C编写并链接到python解释器的放到模块

3,import

1)示例文件:自定义模块my_module.py,文件名my_module.py,模块名my_module

json 14json 15

#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

View Code

模块可以分包可实施的讲话和函数的定义,那几个话语的目标是早先化模块,它们只在模块名第一回相见导入import语句时才实施(import语句是可以在程序中的任意地方运用的,且针对同3个模块很import数11回,为了避免你再次导入,python的优化手段是:第3次导入后就将模块名加载到内存了,后续的import语句仅是对曾经加载大内存中的模块对象扩张了三遍引用,不会再也履行模块内的口舌)

#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
'''
#调用了多次但是只打印了一个结果

作者们可以从sys.modules中找到当前早已加载的模块,sys.modules是贰个字典,内部含有模块名与模块对象的照射,该字典决定了导入模块时是还是不是要求再行导入。

2)每一个模块都是贰个独自的名目空间,定义在那一个模块中的函数,把那几个模块的称号空间作为全局名称空间,那样大家在编制自个儿的模块时,就不要顾虑大家定义在祥和模块中全局变量会在被导入时,与使用者的全局变量争辨

#测试一:money与my_module.money不冲突
#demo.py
#my_module中:from the my_module.py
import my_module
money=10
print(my_module.money)

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

3)测试二:read1与my_module.read1不冲突

#测试二:read1与my_module.read1不冲突
#demo.py
#my_module:
    #print('from the my_module.py')
    #def read1():
        # print('money 1000')   
import my_module
def read1():
    print('========')
my_module.read1()

'''
执行结果:
from the my_module.py
my_module->read1->money 1000
'''                        

4)测试三:执行my_module.change()操作的全局变量money仍旧是my_module中的

#测试三:执行my_module.change()操作的全局变量money仍然是my_module中的
#demo.py
import my_module
money=1
my_module.change()
print(money)

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

5)

计算:第一回导入模块my_module时会做三件事:

1.为源文件(my_module模块)创建新的名称空间,在my_module中定义的函数和措施倘诺使用到了global时访问的就是其一名号空间。

2.在新创立的命名空间中履行模块中蕴藏的代码,见起开始入import my_module

导入模块时到底执行了什么?

事实上函数定义也是“被执行”的语句,模块级别函数定义的执行将函数名放入模块全局名称空间表,用globals()可以查看

3.创设名字my_module来引用该命名空间

1 这个名字和变量名没什么区别,都是‘第一类的’,且使用my_module.名字的方式可以访问my_module.py文件中定义的名字,my_module.名字与test.py中的名字来自两个完全不同的地方。

6)为模块名起别名,约等于m1=1;m2=m1

import my_module as sm
print(sm.money)

以身作则用法一:

有两中sql模块mysql和oracle,依据用户的输入,接纳区其他sql功用

#mysql.py
def sqlparse():
    print('from mysql sqlparse')
#oracle.py
def sqlparse():
    print('from oracle sqlparse')

#test.py
db_type=input('>>: ')
if db_type == 'mysql':
    import mysql as db
elif db_type == 'oracle':
    import oracle as db

db.sqlparse() 
复制代码

4,from … import…

from my_module import read1,read2
这样在当前位置直接使用read1和read2就好了,执行时,仍然以my_module.py文件全局名称空间

from demo import money,read
print(money)
read()
money = 200
read()

json 16json 17

#测试一:导入的函数read1,执行时仍然回到my_module.py中寻找全局变量money
#demo.py
from my_module import read1
money=1000
read1()
'''
执行结果:
from the my_module.py
spam->read1->money 1000
'''

#测试二:导入的函数read2,执行时需要调用read1(),仍然回到my_module.py中找read1()
#demo.py
from my_module import read2
def read1():
    print('==========')
read2()

'''
执行结果:
from the my_module.py
my_module->read2 calling read1
my_module->read1->money 1000
'''

诸如此类在当前义务一向动用read1和read2就好了,执行时,依旧以my_module.py文件全局名称空间

比方当前有重名read1可能read2,那么会有覆盖效果

#测试三:导入的函数read1,被当前位置定义的read1覆盖掉了
#demo.py
from my_module import read1
def read1():
    print('==========')
read1()
'''
执行结果:
from the my_module.py
==========
'''

亟待越发强调的有个别是:python中的变量赋值不是一种存储操作,而只是一种绑定关系,如下:

from my_module import money,read1
money=100 #将当前位置的名字money绑定到了100
print(money) #打印当前的名字
read1() #读取my_module.py中的名字money,仍然为1000

'''
from the my_module.py
my_module->read1->money 1000
'''

1)as

也支持as

from my_module import read1 as read

2)也支撑多行输入

from my_module import (read1,
                  read2,
                 money)

5,把模块当做脚本执行

咱俩得以因此模块的全局变量__name__来查看模块名:
作为脚本运维:
__name__ 等于’__main__json,’

作为模块导入:
__name__= 模块名

效益:用来控制.py文件在不相同的采纳场景下实施不一的逻辑
if __name__ == ‘__main__’:

def fib(n):   
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

if __name__ == "__main__":
    print(__name__)
    num = input('num :')
    fib(int(num))

6模块搜索路径

python解释器在运维时会活动加载一些模块,可以使用sys.modules查看

在首先次导入某些模块时(比如my_module),会先检查该模块是或不是早已被加载到内存中(当前实施文书的名称空间对应的内存),如果有则一向引用

一旦没有,解释器则会寻找同名的内建模块,如若还并未找到就从sys.path给出的目录列表中各种寻找my_module.py文件。

之所以总计模块的寻找顺序是:内存中已经加载的模块->内置模块->sys.path路径中蕴藏的模块

亟需尤其注意的是:大家自定义的模块名不该与系统内置模块重名。尽管每一回都说,可是如故会有人不停的犯错。

 

模块统计:

1,import和from
import都扶助as重命名,都帮助多名字的导入

2,3个模块被import导入之后,并不会重复被导入。因为sys.mouldes记录了全体被导入的模块

3,sys.path记录了导入模块的时候寻找的持有路线

 4,模块就是3个py文件

 5,__all__必须与*连用

相关文章

网站地图xml地图