月度归档:2016年02月

应用日志压缩与python字符问题小结

    年末了,事情不太多, 就规划着将开发的基层服务完善下。在生产环境查看问题时,如果日志不够完善,将会花费较多时间,所以一定要有一个靠谱的日志系统。本次日志系统主要会收集应用的数据交互情况, 包括db操作、redis操作、API操作等,因为日志量比较大,所以一定要将日志尽量的压缩。比如保存python字符串时中文字符的长度就会小一些, ( 试试 len("中文") == 6   , len(u"中文") == 2 ) 在进行服务器日志压缩过程中,发现从db中取出的字段内容都是 "\u559c\u6b22\u4e00\u4e2a\u4eba" , 这样会有两个问题:

1. 中文不直接显示,后期查看时需要再转一下;

2. 存放时多占用了多个字符, \u559c 就当做了6个字符来存放了。 

然后就开始了转码之旅:

因为"\u559c\u6b22\u4e00\u4e2a\u4eba" 这样的字符本身已经是 escape序列了,那么什么叫做escape序列的字符串呢, 简单来说就是为了保存string到db等地方, python自动为这个string中除了字母和数字以外的字符,都加上一个反斜线, 比如在re模块中

>>> print re.escape('test_@#$')
test\_\@\#\$

  所以,对于这个已经是escape序列的unicode,我们只需要反转一下,然后正常显示即可:

首先,先来个粗暴的 ,因为json 的dumps 方法自带是个escape序列的转换参数,我们先使用json来转换一下,再反转一下:

result = json.dumps(json.loads(result), ensure_ascii=False) 


可以正常显示中文了。 查看 ensure_ascii=False 这个参数,主要是引入了 escape 序列转换。

然后, 来一个优雅一点的:

result = result.decode('unicode_escape')  # 此处使用raw_unicode_escape效果是一样的

最后,来个简洁的, 其实我们直接转换这个unicode编码的字符串就行了,

 result = eval("u'" + result + "'")

至此,问题已经解决。

然后我们就来复习一下unicode 编码和解码的知识点:


# python 2.x str 转 unicode: 
str_string.decode('original_encoding')
# s.decode 将s解码成unicode,参数指定的是s本来的编码方式。这个和unicode(s,encodename)是一样的。

# unicode 转 str:
unicode_string.encode('target_encoding')
​# u.encode 将unicode编码成str对象,参数指定使用的编码方式

 

标准编码

编码                                                      描述
utf-8                                    变量长度为8 的编码(默认编码)
utf-16                                  变量长度为16 的编码(大/小端)
utf-16-le                             小端UTF-16 编码
utf-16-be                           大端UTF-16 编码
ascii 7-bit                          7 位ASCII 码表
iso-8859-1                        ISO 8859-1 (Latin-1) 码表
unicode-escape              (定义见Python Unicode 构造函数)
raw-unicode-escape      (定义见Python Unicode 构造函数)
native                                 Python 用的内部格式