python2编码总结(转)

以下依次列出python2常遇到的几个问题及讲解。

 

# -*- coding:utf-8 -*-

python2默认以ASCII编码,但是在实际编码过程中,我们会用到很多中文,为了不使包含中文的程序报错,也是为了符合国际通用惯例,一般将我们的文件编码设置为utf-8格式。

设定编码的格式有很多种,只要第一行或者第二行的声明符合正则表达式 "coding[:=]\s*([-\w.]+)" 即可,一般的声明方式为#-*- coding:utf-8 -*-。

str = "你好"
print str

  运行以上代码,程序会报错:SyntaxError: Non-ASCII character '\xe4' in file D:/TestPython/test/111.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details。这是提示程序中有非ASCII编码的字符。如果加上utf-8声明,程序就不会报错。

# -*- coding:utf-8 -*-

str = "你好"
print str

  虽然以上写法不会报错,但是输出的却是乱码,为什么呢?这就是下面要讲的内容。

 

encode和decode

讲解编码和解码之前,先来讲讲Unicode和utf-8的关系,推荐这篇博客给大家。

可以这样来理解:字符串是由字符构成,字符在计算机硬件中通过二进制形式存储,这种二进制形式就是编码。如果直接使用 “字符串️字符️二进制表示(编码)” ,会增加不同类型编码之间转换的复杂性。所以引入了一个抽象层,“字符串️字符️与存储无关的表示️二进制表示(编码)” ,这样,可以用一种与存储无关的形式表示字符,不同的编码之间转换时可以先转换到这个抽象层,然后再转换为其他编码形式。在这里,unicode 就是 “与存储无关的表示”,utf—8 就是 “二进制表示”。

python2中字符串有两种表示形式,str和unicode。str可以理解为上面这段话中的二进制编码格式,unicode可以理解为抽象层。encode是编码,即从unicode格式到二进制的编码格式如utf-8、gb2312等。decode是解码,即从二进制编码格式到unicode编码格式。

下面请看代码:

# -*- coding:utf-8 -*-

str1 = "你好"print type(str1)str2 = str1.decode("utf-8")print type(str2)

  str1是str类型, 通过decode转为了unicode类型。

下面看encode代码:

# -*- coding:utf-8 -*-

str1 = u"你好"
print type(str1)
str2 = str1.encode("utf-8")
print type(str2)

  str1是unicode类型,通过encode转为了str类型。

 

我们再回头看最开始留下的问题,那段代码为什么会输出乱码呢。因为文件规定的编码格式是utf-8,但是我们print是打印到控制台的,控制台无法显示utf-8编码格式的字符。所以我们要转一下格式。

# -*- coding:utf-8 -*-

str = "你好"
str = str.decode("utf-8")
print str

  很多时候编码解码的时候需要加ignore参数才能正确转换,例如.encode('utf-8', 'ignore')或.decode('utf-8', 'ignore'),大家自行斟酌吧。

 

chardet获取编码格式

有些时候我们是无法知道字符串是什么编码的,比如抓取网页时,有些是utf-8的,有些是gb2312编码的,那我们该怎么获取编码格式并转换为unicode呢。这里就介绍到一个第三方库chardet。使用方式大概如下:

# -*- coding: utf-8 -*-

import chardet

str = "xxxxx"
str_type = chardet.detect(str)
code = str_type['encoding']

  code即为str的编码格式。但有些人反映该方法得到的编码格式不准确,速度也慢。本人亲测,速度确实一般,但是目前还没遇到不准确的情况。大家可以斟酌使用,我这里只是提供一个思路,如果谁那里有更好的方式,可以告知小弟,不吝赐教才是。

 

import sys

reload(sys)

sys.setdefaultencoding('utf8')

之前也遇到过很莫名其妙的编码错误,网上搜到这种方法能解决就糊里糊涂的用上了,也不知是什么原理。今天看到一篇不错的博客,推荐给大家:http://blog.csdn.net/crazyhacking/article/details/39375535。以下内容引用自该篇文章:

Python 里面的编码和解码也就是 unicode 和 str 这两种形式的相互转化。编码是 unicode -> str,相反的,解码就是 str -> unicode。剩下的问题就是确定何时需要进行编码或者解码了.关于文件开头的"编码指示",也就是 # -*- coding: -*- 这个语句。Python 默认脚本文件都是 UTF-8 编码的,当文件中有非 UTF-8 编码范围内的字符的时候就要使用"编码指示"来修正. 关于 sys.defaultencoding,这个在解码没有明确指明解码方式的时候使用。比如我有如下代码:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
s = '中文'  # 注意这里的 str 是 str 类型的,而不是 unicode
s.encode('gb18030') 

这句代码将 s 重新编码为 gb18030 的格式,即进行 unicode -> str 的转换。因为 s 本身就是 str 类型的,因此 Python 会自动的先将 s 解码为 unicode ,然后再编码成 gb18030。因为解码是python自动进行的,我们没有指明解码方式,python 就会使用 sys.defaultencoding 指明的方式来解码。很多情况下 sys.defaultencoding 是 ANSCII,如果 s 不是这个类型就会出错。拿上面的情况来说,我的 sys.defaultencoding 是 anscii,而 s 的编码方式和文件的编码方式一致,是 utf8 的,所以出错了:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position
0: ordinal not in range(128)
对于这种情况,我们有两种方法来改正错误:
一是明确的指示出 s 的编码方式 

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

s = '中文'
s.decode('utf-8').encode('gb18030') 

二是更改 sys.defaultencoding 为文件的编码方式 

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

import sys
reload(sys) # Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入
sys.setdefaultencoding('utf-8') 

str = '中文'
str.encode('gb18030')

看完之后,改成这样

print "<p>addr:", form["addr"].value.decode('gb2312').encode('utf-8')
成功通过.

  但是这种方式用着就是别扭,还是尽量自己来控制编码,明确了编码格式,自己写着也踏实。

 

个人总结

实际编程过程中,最好能在代码内统一编码格式,比如统一为unicode,因为这样就不用考虑编码的问题了。到了显示或输出时再转换为存储类型(utf-8、GBK)。

 

以上为最近编写python代码的过程中遇到的一些问题及总结,如果有什么不对的地方还请大家及时回复交流,在此谢过。

http://www.cnblogs.com/jinhaolin/p/5128973.html

时间: 2024-11-08 19:01:44

python2编码总结(转)的相关文章

python3编码问题汇总_python

这两天写了个监测网页的爬虫,作用是跟踪一个网页的变化,但运行了一晚出现了一个问题....希望大家不吝赐教! 我用的是python3,错误在对html response的decode时抛出,代码原样为: response = urllib.urlopen(dsturl) content = response.read().decode('utf-8') 抛出错误为 File "./unxingCrawler_p3.py", line 50, in getNewPhones content

编码-python2.7.5以ucs4编译

问题描述 python2.7.5以ucs4编译 为什么用这些命令编译安装的还是ucs-2编码方式呢? ./configure --prefix=/usr/local/python27 --enable-shared -enable-unicode=ucs4 make && make install 解决方案 http://blog.csdn.net/shuifa2008/article/details/41789043 解决方案二: python ucs-2与ucs-4编码方式判断使用vs

界面-python2.7 编码问题,在线等,急

问题描述 python2.7 编码问题,在线等,急 python脚本用到了pyqt设计界面,代码中得到某一个路径变量, self.svn_cmd_ex_resc = 'svn checkout ' + self.URL + '/trunk/resource '+ self.resc_dstpath 运行时这里报错,脚本开头用了# -*- coding: utf-8 -*- self.svn_cmd_ex_resc = 'svn checkout ' + self.URL + '/trunk/re

详解Python2.x中对Unicode编码的使用_python

我确定有很多关于Unicode和Python的说明,但为了方便自己的理解使用,我还是打算再写一些关于它们的东西.  字节流 vs Unicode对象 我们先来用Python定义一个字符串.当你使用string类型时,实际上会储存一个字节串.   [ a ][ b ][ c ] = "abc" [ 97 ][ 98 ][ 99 ] = "abc" 在这个例子里,abc这个字符串是一个字节串.97.,98,,99是ASCII码.Python 2.x版本的一个不足之处就是

python2.7的编码问题与解决方法_python

前言 Python的编码问题基本是每个新手都会遇到的坎,但只要完全掌握了就跳过了这个坑,万变不离其中,下面给大家整理了在python2.7遇到的编码问题,下面来一起看看吧. 一.直接在python文件内修改系统编码 默认的编码格式是ascii,我们可以直接修改为utf-8 import sys reload(sys) sys.setdefaultencoding('utf-8') 二.在输入输出的时候,修改编码格式 # 解码为GBK,再次编码为UTF-8 html_doc = unicode(h

python编码最佳实践之总结

该文章转自阿里巴巴技术协会(ATA) 作者:空溟    相信用python的同学不少,本人也一直对python情有独钟,毫无疑问python作为一门解释性动态语言没有那些编译型语言高效,但是python简洁.易读以及可扩展性等特性使得它大受青睐.      工作中很多同事都在用python,但往往很少有人关注它的性能和惯用法,一般都是现学现用,毕竟python不是我们的主要语言,我们一般只是使用它来做一些系统管理的工作.但是我们为什么不做的更好呢?python zen中有这样一句:There s

python编码处理

开始 用python处理中文时,读取文件或消息,http参数等等 一运行,发现乱码(字符串处理,读写文件,print) 然后,大多数人的做法是,调用encode/decode进行调试,并没有明确思考为何出现乱码 所以调试时最常出现的错误 错误1 Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: 'ascii' codec can't

Python编码错误的处理

如题,我用python 解析文件(文件中含有中文),并写入其他文件时报错: UnicodeEncodeError: 'ascii' codec can't encode characters 经过google大神的指导,确定以下解决方式: #coding:utf-8import sys reload(sys) sys.setdefaultencoding('utf-8') 疑问:为什么需要reload呢? grep -r -i 'setdefaultencoding' /usr/lib/pyth

网页的字符集和编码

一.什么是字符集?什么是编码? 字符(Character)是文字与符号的总称,包括文字.图形符号.数学符号等. 一组抽象字符的集合就是字符集(Charset). 字符集常常和一种具体的语言文字对应起来,该文字中的所有字符或者大部分常用字符就构成了该文字的字符集,比如英文字符集. 一组有共同特征的字符也可以组成字符集,比如繁体汉字字符集.日文汉字字符集. 字符集的子集也是字符集. 计算机要处理各种字符,就需要将字符和二进制内码对应起来,这种对应关系就是字符编码(Encoding). 制定编码首先要