Python2.7 json.loads() 出现的unicode编码问题

python2真是神坑,建议能用python3就用python3,无奈。。。。。。。

笔者原本需要将一个python文件获得的数据进行一定的处理,美观地显示在命令行上。

数据如下,输出的是一个json对象数组转换后的字符串,这里叫resultList。

[
    {
        'loginName': 'user7',
        'dirPermission': {
            'other': 'other',
            'mkdir': 'mkdir'
        },
        'shareType': 'ftp',
        'accessMode': 'vir_user',
        'rwState': 'rw',
        'usedSize': 0,
        'sharedDir': '/home/vsftpd/share7',
        'filePermission': {
            'download': 'false',
            'upload': 'upload'
        }
    },
    {
        'loginName': 'user1',
        'dirPermission': {
            'other': 'false',
            'mkdir': 'mkdir'
        },
        'shareType': 'ftp',
        'accessMode': 'vir_user',
        'rwState': 'rw',
        'usedSize': 0,
        'sharedDir': '/home/vsftpd/share1',
        'filePermission': {
            'download': 'download',
            'upload': 'upload'
        }
    },
    {
        'loginName': 'user6',
        'dirPermission': {
            'other': 'false',
            'mkdir': 'false'
        },
        'shareType': 'ftp',
        'accessMode': 'vir_user',
        'rwState': 'ro',
        'usedSize': 0,
        'sharedDir': '/home/vsftpd/share6',
        'filePermission': {
            'download': 'false',
            'upload': 'false'
        }
    },
    {
        'loginName': 'user2',
        'dirPermission': {
            'other': 'other',
            'mkdir': 'mkdir'
        },
        'shareType': 'ftp',
        'accessMode': 'vir_user',
        'rwState': 'rw',
        'usedSize': 442,
        'sharedDir': '/home/vsftpd/share2',
        'filePermission': {
            'download': 'false',
            'upload': 'upload'
        }
    }
]

正常情况下直接json.loads(resultList)就可以转换成json对象数组,然后开始各种骚操作。

但是坑来了,

1  #!/usr/bin/env python
2  #-*-coding:utf-8-*-
3
4  import os
5  import json
6  from prettytable import PrettyTable
7 
8  process = os.popen("python /usr/local/script/ftp_list.py")
9  resultList = process.read().strip("\n")
10 process.close()
11 resultList = json.loads(resultList)
12
13 list = PrettyTable(["sharedDir", "accessMode", "usedSize", "rwState", "mkdir", "other", "upload", "download", "loginName"])
14 list.align["sharedDir"] = "1"
15 list.padding_width = 1
16 for i in resultList:
17    list.add_row([i["sharedDir"], i["accessMode"], i["usedSize"], i["rwState"], i["dirPermission"]["mkdir"], i["dirPermission"]["other"], i["filePermission"]["upload"], i["filePermission"]["download"], i["loginName"]])
18 print(list)

执行python脚本,报错:

呵呵,赶紧百度

发现一个帖子,说可能是json格式有问题,我赶紧打开在想JSON校验网站,粘贴我得到的json数据,

 

全错是什么鬼,我明明写的这么规范。。

继续百度,哦豁,有文章说json字符串最外层要是单引号,内层的key和value要是双引号,赶紧把里面的单引号改成双引号,果然不报错了。

然后加入一行代码:

resultList = resultList.replace("'", '"')

把所有的单引号转化为双引号不就ok了,结果、、、

json对象数组的key和value前面都出现了u,原因是python 2下使用json.loads往往会导致最终的结果编码是unicode,并不是我们想要的str型

参考这篇文章

https://blog.csdn.net/qq_24342335/article/details/84561341

解决方案是对这种得到的json对象数组进行遍历,转码,就ok了。

#!/usr/bin/env python
#-*-coding:utf-8-*-

import os
import json
from prettytable import PrettyTable

def unicode_convert(input):
    if isinstance(input, dict):
        return {unicode_convert(key): unicode_convert(value) for key, value in input.iteritems()}
    elif isinstance(input, list):
        return [unicode_convert(element) for element in input]
    elif isinstance(input, unicode):
        return input.encode('utf-8')
    else:
        return input

process = os.popen("python /usr/local/script/ftp_list.py")
resultList = process.read().strip("\n")
process.close()

resultList = resultList.replace("'", '"')
resultList = unicode_convert(json.loads(resultList))

list = PrettyTable(["sharedDir", "accessMode", "usedSize", "rwState", "mkdir", "other", "upload", "download", "loginName"])
list.align["sharedDir"] = "1"
list.padding_width = 1
for i in resultList:
    list.add_row([i["sharedDir"], i["accessMode"], i["usedSize"], i["rwState"], i["dirPermission"]["mkdir"], i["dirPermission"]["other"], i["filePermission"]["upload"], i["filePermission"]["download"], i["loginName"]])
print(list)

下面分析unicode_convert()这个函数:

isinstance是python内置的判断数据类型的函数,函数内部遍历json,递归调用该函数,如果编码为unicode,则改为utf-8。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值