json 模块
json介绍:
json(javascript object notation)全称是javascript对象表示法,它是一种数据交换的文本格式,而不是一种编程语言,用于读取结构化数据。2001年由Douglas Crockford提出,目的是取代繁琐笨重的XML格式。
下面介绍的语法规则是在js中介绍的
json语法规则
【1】简单值
字符串必须使用双引号表示,不能使用单引号。数值必须以十进制表示,且不能使用NaN和Infinity。JSON不支持javascript中的特殊值undefined
#合格的简单值 1 "hello python" true null
#不合格的简单值 +0x1 'hello world' undefined NaN Infinity
【2】对象
对象作为一种复杂数据类型,表示的是一组有序的键值对儿。而每个键值对儿中的值可以是简单值,也可以是复杂数据类型的值
与javascript的对象字面量相比,JSON有三个不同的地方
1、JSON没有变量的概念
2、JSON中,对象的键名必须放在双引号里面
3、因为JSON不是javascript语句,所以没有末尾的分号
4、同一个对象中不应该出现两个同名属性
#合格的对象 { "name":"今晚打老虎", "age":18, "school":{ "name":"pengzhong", "location":"shanwei" } }
#不合格的对象 { name: "小明", 'age': 32 }#属性名必须使用双引号 {};#不需要末尾的分号
【3】数组
数组也是一种复杂数据类型,表示一组有序的值的列表,可以通过数值索引来访问其中的值。数组的值也可以是任意类型——简单值、对象或数组。
JSON数组也没有变量和分号,把数组和对象结合起来,可以构成更复杂的数据集合。数组或对象最后一个成员的后面,不能加逗号
eval()函数
首先先介绍下eval()函数
语法:eval(source[, globals[, locals]])
作用:将字符串当成有效的表达式来求值并返回计算结果。参数:source:一个Python表达式或函数compile()返回的代码对象;globals:可选。必须是dictionary;locals:可选。任意map对象。
#######字符串转换成列表########## str = "[1,2,3]" print(type(str)) #<class 'str'> list = eval(str) print(list) #[1, 2, 3] print(type(list)) #<class 'list'> ########字符串转换成字典######### str = "{1: 'a', 2:'b'}" print(type(str)) #<class 'str'> dict = eval(str) print(dict) #{1: 'a', 2: 'b'} print(type(dict)) #3<class 'dict'>
a = b = 1 add = eval("a + b") print(add) #2 def test(): a = b = 2 num2 = eval("a + b") print(num2) #4 num3 = eval("a + b",globals()) num4 = eval("a + b",globals(),locals()) print(num3) # 2 print(num4) #4 test() print(locals()["a"]) #1 print(locals()["b"]) #1 print(globals()["a"]) #1 print(globals()["b"]) #1
eval()使用原因:
1)在编译语言里要动态地产生代码,基本上是不可能的,但动态语言是可以,意味着软件已经部署到服务器上了,但只要作很少的更改,只好直接修改这部分的代码,就可立即实现变化,不用整个软件重新加载。
2)在machin learning里根据用户使用这个软件频率,以及方式,可动态地修改代码,适应用户的变化。
eval()的安全性问题,总结来说就是eval函数将字符串转换成对象并运行,比如你对文件的增删改成
eval("__import__('os').system('ls')") #打印出当前文件夹下的所有文件
json模块
序列化
我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
【1】dumps()
将“对象”转换成“字符串类型”
import json dic = {'name': 'hugo','age': 18} print(type(dic)) #<class 'dict'> st = json.dumps(dic) print(st) #<class 'dict'> print(type(st)) #<class 'dict'>
【2】loads() 将“字符串”转换成“对象”
import json dic = {'name': 'hugo','age': 18} print(type(dic)) #<class 'dict'> dumps = json.dumps(dic) #<class 'dict'> print(dumps) #<class 'dict'> print(type(dumps)) loads = json.loads(dumps) print(loads) #<class 'dict'> print(type(loads)) #<class 'dict'>
【3】dump() json.dump()用于将“对象”(dict类型等)的数据转成str,并写入到json文件中。
######序列化
import json dic = {'name': 'hugo', 'age': 18} print(type(dic)) #<class 'dict'> st = json.dumps(dic) print(type(st)) #<class 'str'> f = open("json文件", 'w') f.write(st) #######相当于:json.dump(dic,f) f.close()
json文件的内容如下:
{"name": "hugo", "age": 18}
【4】load() 用于从json文件中读取数据。
#####反序列化
import json f = open("json文件") data = json.loads(f.read())######相当于data=json.load(f) print(data) #{'name': 'hugo', 'age': 18}
注:通过eval()将数据转换成字符串也可以,但是由于eval()的安全性,不建议使用
注意
json文件的内容如下
{'name': "hugo", "age": 18}
import json with open("json文件", "r") as f: data = f.read() data = json.loads(data) print(data["name"]) #报错,因为"json文件的内容"中,name包裹的是单引号,json只认识双引号,不认识单引号
json文件的内容如下
{"name": "hugo", "age": 18}
import json with open("json文件", "r") as f: data = f.read() data = json.loads(data) print(data["name"]) #hugo