第4章 文本和字节序列
[toc]
编码和解码
markdom可以插入emoji表情包
其中作为前缀,x1f54为对应表情的unicode编码
?
emoji
把码位转换成字节序列的过程是编码;把字节序列转换成码位的过程是解码
decode的作用是将其他编码的字符串转换成unicode编码
如str1.decode('gb2312'),表示将gb2312编码的字符串转换成unicode编码。encode的作用是将unicode编码转换成其他编码的字符串
如str2.encode('gb2312'),表示将unicode编码的字符串转换成gb2312编码。
Python 3默认使用UTF-8编码源码
,Python 2(从2.5开始)则默认使用ASCII。
如果加载的.py模块中包含UTF-8之外的数据,而且没有声明编码,会报错
title: python 2 编解码过程
编码前其他编码字符串->unicode: 编码 decode
unicode->>编码后其他编码字符串:解码 encode
在新版本的python3中,取消了unicode类型,代替它的是使用unicode字符的字符串类型(str),字符串类型(str)成为基础类型
如下所示,而编码后的变为了字节类型(bytes)
title: python 3 编解码过程
编码前其他编码字符串->str(unicode): 编码 decode
str(unicode)->>编码后其他编码字符串:解码 encode
# 指定字符串类型对象u
u = "中文"
print(u, type(u))
# 以gb2312编码对u进行编码,获得bytes类型对象str
str = u.encode('gb2312')
print(str, type(str))
# 以gb2312编码对字符串str进行解码,获得字符串类型对象u1
u1 = str.decode('gb2312')
print(u1, type(u1))
返回结果:
中文 <class 'str'>
b'\xd6\xd0\xce\xc4' <class 'bytes'>
中文 <class 'str'>
chardet模块
chardet模块检测读取出来的str是什么编码格式的
from urllib.request import urlopen
import chardet
rawdata = urlopen('http://baidu.com/').read()
chr = chardet.detect(rawdata)
print(chr) # {'encoding': 'ascii', 'confidence': 1.0, 'language': ''}
json.dumps在默认情况下,对于非ascii字符生成的是相对应的字符编码,而非原始字符.
首先明确,chardet这个是判断编码
而不是判断数据类型的,
其次,加encode只是将其变成了字节,
chardet只能够接受字节而不能接收字符类型的
import json
import chardet
dict1 = {"haha": "哈哈"}
# json.dumps 默认ascii编码
print(json.dumps(dict1)) # {"haha": "\u54c8\u54c8"}
# 禁止ascii编码后默认utf-8
print(json.dumps(dict1, ensure_ascii=False)) # {"haha": "哈哈"}
# ascii
ss = chardet.detect(json.dumps(dict1).encode())
print(ss)
# utf-8
ss = chardet.detect(json.dumps(dict1, ensure_ascii=False).encode())
print(ss)
json与字典区别
在python中,字典的输出内容跟json格式内容一样,但是字典的格式是字典,json的格式是字符串,所以在传输的时候(特别是网页)要转换使用。
重要函数
编码:把一个Python对象编码转换成Json字符串 json.dumps()
解码:把Json格式字符串解码转换成Python对象 json.loads()
举个例子:
import json
dic = {'str': 'this is a string', 'list': [1, 2, 'a', 'b']}
print(type(dic)) # <class 'dict'>
print(dic)
json_obj = json.dumps(dic)
print(type(json_obj)) # <class 'str'>
print(json_obj)
dic1 = json.loads(json_obj)
print(type(dic1)) # <class 'dict'>
print(dic1)
几个主要函数
dump,dumps,load,loads
带s跟不带s的区别是 带s的是对 字符串的处理,而不带 s的是对文件对像的处理。
import json
from io import StringIO
# 创建文件流对象
io = StringIO()
# 把 json编码数据导向到此文件对象
json.dump(['streaming API'], io)
# 取得文件流对象的内容
print(io.getvalue()) # ["streaming API"]
参数ensure_ascii
默认为True,所有的非ascii字符在输出时都会被转义为uxxxx的序列,
返回的对象是一个只由ascii字符组成的str类型,为False时不会进行转义输出,反回的对象是个unicode。(这个参数对包含中文的json输出时非常有用)
举个例子:
import json
data = {u'我': u'是', u'美': u'女'}
print(json.dumps(data)) # {"\u6211": "\u662f", "\u7f8e": "\u5973"}
print(json.dumps(data, ensure_ascii=False)) # {"我": "是", "美": "女"}
处理中文json时,要想不每次都给一堆重复的参数,可以用partial
import json
from functools import partial
json_dumps = partial(json.dumps, ensure_ascii=False, sort_keys=True)
data = {u'我': u'是', u'美': u'女'}
print(json_dumps(data)) # {"我": "是", "美": "女"}
看一个例子:
import json
# 使用双引号、单引号都可以的,建议使用双引号
h = '{"foo":"bar", "foo2":"bar2"}'
d = "{'muffin' : 'lolz', 'foo' : 'kitty'}"
json_obj1 = json.dumps(h)
json_obj2 = json.dumps(d)
dic1 = json.loads(json_obj1)
dic2 = json.loads(json_obj2)
print("json_obj1=", json_obj1)
print("json_obj2=", json_obj2)
print("dic1=", dic1)
print("dic1 type=", type(dic1))
print("dic2=", dic2)
print("dic2 type=", type(dic2))
总结:
Python 的字典是一种数据结构,JSON 是一种数据格式。
Python的字典key可以是任意可hash对象,json只能是字符串
json模块和simplejson模块
环境:
python 3.6+
json: 2.0.9
simplejson: 3.16.0
- 区别1
import json
import simplejson
json_str = b'hello'
json_str = json_str.decode() # 使用json模块必须要先加入这一行否则会报错
print(json.dumps(json_str))
print(simplejson.dumps(json_str))
比较性能方面的差异:
压测脚本:
import timeit
import simplejson
import pickle
import json
times = 100
print("Times are for %i iterations" % times)
f = open('words.pickle', "rb")
words = pickle.load(f)
f.close()
def bench(cmd, imprt):
t = timeit.Timer(cmd, imprt)
s = t.timeit(number=times)
print("%s total=%02f avg=%02f" % (cmd, s, (s / times)))
return s
def simplejson_loads():
simplejson.loads(simplejson.dumps(words))
def simplejson_dumps():
simplejson.dumps(words)
b1 = bench('simplejson_loads()', 'from __main__ import simplejson_loads')
b2 = bench('simplejson_dumps()', 'from __main__ import simplejson_dumps')
def json_dumps():
json.dumps(words)
def json_loads():
json.loads(json.dumps(words))
b3 = bench('json_loads()', 'from __main__ import json_loads')
b4 = bench('json_dumps()', 'from __main__ import json_dumps')
返回结果是:
Times are for 100 iterations
simplejson_loads() total=1.760785 avg=0.017608
simplejson_dumps() total=0.921571 avg=0.009216
json_loads() total=1.351725 avg=0.013517
json_dumps() total=0.716219 avg=0.007162
从上面结果可以看到json 在loads操作和dumps操作都比simplejson好
网上说的simplejson比json快,感觉说的不对
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。