以下依次列出python2常遇到的几个问题及讲解。
# -*- coding:utf-8 -*- python2默认以ASCII编码,但是在实际编码过程中,我们会用到很多中文,为了不使包含中文的程序报错,也是为了符合国际通用惯例,一般将我们的文件编码设置为utf-8格式。 设定编码的格式有很多种,只要第一行或者第二行的声明符合正则表达式 "coding[:=]\s*([-\w.]+)" 即可,一般的声明方式为#-*- coding:utf-8 -*-。
运行以上代码,程序会报错:SyntaxError: Non-ASCII character '\xe4' in file D:/TestPython/test/111.py on line 1, but no encoding declared; see http:///dev/peps/pep-0263/ for details。这是提示程序中有非ASCII编码的字符。如果加上utf-8声明,程序就不会报错。
虽然以上写法不会报错,但是输出的却是乱码,为什么呢?这就是下面要讲的内容。
encode和decode 讲解编码和解码之前,先来讲讲Unicode和utf-8的关系,推荐这篇博客给大家。 可以这样来理解:字符串是由字符构成,字符在计算机硬件中通过二进制形式存储,这种二进制形式就是编码。如果直接使用 “字符串??字符??二进制表示(编码)” ,会增加不同类型编码之间转换的复杂性。所以引入了一个抽象层,“字符串??字符??与存储无关的表示??二进制表示(编码)” ,这样,可以用一种与存储无关的形式表示字符,不同的编码之间转换时可以先转换到这个抽象层,然后再转换为其他编码形式。在这里,unicode 就是 “与存储无关的表示”,utf—8 就是 “二进制表示”。
python2中字符串有两种表示形式,str和unicode。str可以理解为上面这段话中的二进制编码格式,unicode可以理解为抽象层。encode是编码,即从unicode格式到二进制的编码格式如utf-8、gb2312等。decode是解码,即从二进制编码格式到unicode编码格式。
下面请看代码:
# -*- coding:utf-8 -*- str1是str类型, 通过decode转为了unicode类型。 下面看encode代码:
str1是unicode类型,通过encode转为了str类型。
我们再回头看最开始留下的问题,那段代码为什么会输出乱码呢。因为文件规定的编码格式是utf-8,但是我们print是打印到控制台的,控制台无法显示utf-8编码格式的字符。所以我们要转一下格式。
很多时候编码解码的时候需要加ignore参数才能正确转换,例如.encode('utf-8', 'ignore')或.decode('utf-8', 'ignore'),大家自行斟酌吧。
chardet获取编码格式 有些时候我们是无法知道字符串是什么编码的,比如抓取网页时,有些是utf-8的,有些是gb2312编码的,那我们该怎么获取编码格式并转换为unicode呢。这里就介绍到一个第三方库chardet。使用方式大概如下:
code即为str的编码格式。但有些人反映该方法得到的编码格式不准确,速度也慢。本人亲测,速度确实一般,但是目前还没遇到不准确的情况。大家可以斟酌使用,我这里只是提供一个思路,如果谁那里有更好的方式,可以告知小弟,不吝赐教才是。
import sys reload(sys) sys.setdefaultencoding('utf8') 之前也遇到过很莫名其妙的编码错误,网上搜到这种方法能解决就糊里糊涂的用上了,也不知是什么原理。今天看到一篇不错的博客,推荐给大家:http://blog.csdn.net/crazyhacking/article/details/39375535。以下内容引用自该篇文章:
但是这种方式用着就是别扭,还是尽量自己来控制编码,明确了编码格式,自己写着也踏实。
个人总结 实际编程过程中,最好能在代码内统一编码格式,比如统一为unicode,因为这样就不用考虑编码的问题了。到了显示或输出时再转换为存储类型(utf-8、GBK)。
以上为最近编写python代码的过程中遇到的一些问题及总结,如果有什么不对的地方还请大家及时回复交流,在此谢过。
|
|
来自: 昵称10504424 > 《工作》