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.youkuaiyun.com/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。