Python字符编码

简介:

  在用python编程中,字符串有两种表示方法"string"和 u"string"。

为什么字符串要是用这两种表达方式。不是仅仅用前一种呢?

      使用type()函数查看,它们各自是str对象和unicode对象。这两个对象有什么差别吗?还有经经常使用到的encode()和decode()又是干什么的呢?都说python脚本使用的是两字节编码,这又是指什么呢?

     要回答上面几个问题,首先得弄清楚关于编码的几个概念:
Character Set:字符集,是我们人能够识别的字符。

如ASCII规定了127个用一个字节能够表示的字符集。包含英文字母、数字、符号和一些控制字符。当然ASCII定义的字符集比較小。

python中的Character Set基本包含眼下世界上全部是用的字符。如中文、英文、日文字符等等。所以基本上全部的字符都可在Python 中进行处理。

Code Point :计算机是不能直接识别字符的(由于它仅仅能直接识别二进制码),所以为了能让计算机处理和存储字符,须要将字符映射成一个数值(由于数值能够用二进制表达,计算机从而就能够识别了),这个数值叫作字符的code point。字符与其code point是一对一映射,Unicode非常好的规定了这样的映射关系。
Encode:unicode尽管规定了每一个字符的Code Point,但并没有规定计算机怎样存储这些Code Point。

全部就有了UTF-8、GBK、UTF-16等编码格式,它们规定计算机怎样来存储这个Code Point,每一个编码格式它们存储方式都是不同样的。比如,“中”字的Code Point为U+2D2E(U表示Unicode,2D2E表示该Code Point值),使用GBK、Big5、UTF-8、UTF-16四种编码协议对该Code Point进行编码。获得的实际二进制表演示样例如以下:

       GBK      Big5        UTF-8     UTF-16
 ~~\xD6\xD0  \xA4\xA4  \xE4\xB8\xAD  \x2D\x4E
Decode:对实际的二进制进行解码。获取它所代表字符的Code Point。如“\xD6\xD0”使用GBK解码,将获得2D2E(“中”的Code Point ),假设使用UTF-8对其进行解码。就会出错。由于它不是用UTF-8编码的。


      上面简介下字符及编码解码的概念,可參考博文《字符的编码与解码》
       Python中使用两种字符串表达方式,是为了区分字符与实际表示字符的二进制信息。

unicode对象用来表示字符。它不涉及字符的底层的二进制编码信息。

str对象是用来表示字符的二进制信息。一个unicode对象能够使用多种编码格式(如UTF8、GBK)编码(encode)成多个str对象。每一个str对象表示该字符串的一种二进制表达。多个不同的str对象能够解码成相等的unicode对象(表示字符串同样。但内存位置不同)。

     unicode的存在也是为了解决因採用不同编码格式导致的一些问题。建议大家使用unicode对象来存放字符串,统一格式。

unicode尽管不规定详细的二进制信息,但为了存放每一个字符的Code Point值,须要两个字节,所以说Python採用的是二进制编码(不知道这么理解可对?)。

     因为str对象没有属性指定它的编码格式。所以对它进行处理时,仅仅能将它看成一个字节串。当对str对象进行打印或解码时。且不知道它的编码格式。那么python仅仅能用默认编码格式对其进行操作。

假设编码不匹配,就会出现乱码或者报错。

str对象:
称字符串,它是字符串使用特定编码格式进行编码后的二进制表达,实际代表用于存储二进制信息的字节串。

所以称它为“字节串”更合适。如

>>> str = '你好'   #採用系统设定的编码格式对“你好”进行编码,可通过locale命令查看。

>>> str '\xe4\xbd\xa0\xe5\xa5\xbd' #当locale设置为utf8时。'你好'的编码后的二进制表达,一个六字节的字节串

Unicode对象

用于表达“字符”,由于计算机不用直接识别字符,所以使用Code Point来取代字符。例如以下:

>>> u"你好"
u'\u4f60\u597d'

Code Point 4F60表示“你”,597d表示“好”。

它仅仅是一个数值与字符映射,不用于详细编码。

       对一个str对象进行解码。能够获得它表达字符串的Code Point,即unicode对象。对unicode对象进行编码。可获得它的实际二进制表达,即str对象。当想把str对象从一中编码格式转换成还有一种编码格式时,首先得把str转换成unicode对象。再从unicode对象转换成第二种编码格式的str对象。

以下运行一个str对象从utf8格式到gbk格式的转换:

>>> str="你好"
>>> str
'\xe4\xbd\xa0\xe5\xa5\xbd'         # 採用OS的utf8编码格式
>>> unicode=str.decode("utf8")     # 解码成Code Point值 
>>> unicode
u'\u4f60\u597d'
>>> str_gbk=unicode.encode("gbk")  # 将Code Point编码成GBK格式
>>> str_gbk
'\xc4\xe3\xba\xc3'

>>> unicode.encode()               # 假设编码不指定格式,将採用系统默认的编码格式进行编码。对于decode也一样。

这里因为ASCII不能对中文字符编码,所以出错了。 Traceback (most recent call last):   File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) >>> u = u"你好"     #前缀u自己主动把字符串从utf8转换成unicode格式了 u'\u4f60\u597d'


写文件:
>>> file=open("test.txt", "a")
>>> file.write(str)
>>> file.write(str_gbk)
>>> file.write(unicode)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
       从上面看。UTF8格式的str对象和GBK格式的str对象成功的写入test.txt文件,然而在将unicode对象写入文件时。出现错误了。

这是为什么呢?

       str对象表示字符串经编码后的二进制信息,能够直接写入文件。

然后unicode对象表示的是字符串的Code Point值,是抽象的值,用来表示字符,是不能直接写入文件的。所以Python试图使用默认的编码格式ASCII。对unicode对象进行编码,然后将结果存入文件。可是因为ASCII不能对”你好”进行编码,所以报错了。


改动系统默认编码格式:
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.setdefaultencoding("gbk")  #不建议这么用[2]

>>> str(unicode)      #使用默认GBK,对unicode("你好")进行编码,转成str对象
'\xc4\xe3\xba\xc3'
>>> unicode.encode()   #使用默认GBK。对unicode("你好")进行编码,转成str对象
'\xc4\xe3\xba\xc3'

>>> "你好".decode()    #由于系统使用UTF8,所以“你好”是UTF8格式的字节串,使用默认GBK对该字节串进行解码,尽管成功执行了,但其结果是不对的。

所以我们须要保证字节串用什么格式编码的。就要用什么格式解码。 u'\u6d63\u72b2\u30bd'

 
 




參考文献:
[1] http://www.newsmth.net/bbscon.php?

bid=284&id=84741

[2] http://stackoverflow.com/questions/3828723/why-we-need-sys-setdefaultencodingutf-8-in-a-py-script
[3] http://www.joelonsoftware.com/articles/Unicode.html
[4] http://www.unicode.org/






本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5077643.html,如需转载请自行联系原作者

相关文章
|
11月前
|
算法 前端开发 数据处理
小白学python-深入解析一位字符判定算法
小白学python-深入解析一位字符判定算法
121 0
|
JavaScript IDE 开发工具
python中的SyntaxError: invalid character in identifier(语法错误:标识符中有无效字符)
【5月更文挑战第14天】python中的SyntaxError: invalid character in identifier(语法错误:标识符中有无效字符)
1342 8
|
12月前
|
Python
python获取字符串()里面的字符
在Python中,如果你想获取字符串中括号(比如圆括号`()`、方括号`[]`或花括号`{}`)内的字符,你可以使用正则表达式(通过`re`模块)或者手动编写代码来遍历字符串并检查字符。 这里,我将给出使用正则表达式的一个例子,因为它提供了一种灵活且强大的方式来匹配复杂的字符串模式。 ### 使用正则表达式 正则表达式允许你指定一个模式,Python的`re`模块可以搜索字符串以查找匹配该模式的所有实例。 #### 示例:获取圆括号`()`内的内容 ```python import re def get_content_in_parentheses(s): # 使用正则表达
262 36
|
10月前
|
人工智能 Shell 开发工具
[oeasy]python0041_输出ASCII码表_英文字符编码_键盘字符_ISO_646
本文介绍了ASCII码表的生成与使用,包括英文字符、数字和符号的编码。通过Python代码遍历0到127的ASCII值,解决了找不到竖线符号的问题,并解释了ASCII码的固定映射关系及其重要性。文章还介绍了ASCII码的历史背景,以及它如何成为国际标准ISO 646。最后,通过安装`ascii`程序展示了完整的ASCII码表。
138 1
|
10月前
|
人工智能 开发工具 Python
[oeasy]python040_缩进几个字符好_输出所有键盘字符_循环遍历_indent
本文探讨了Python代码中的缩进问题。通过研究`range`函数和`for`循环,发现缩进对于代码块的执行至关重要。如果缩进不正确,程序会抛出`IndentationError`。文章还介绍了Python的PEP8规范,推荐使用4个空格进行缩进,并通过示例展示了如何使用Tab键实现标准缩进。最后,通过修改代码,输出了从0到122的字符及其对应的ASCII码值,但未能找到竖线符号(`|`)。文章在总结中提到,下次将继续探讨竖线符号的位置。
120 0
|
12月前
|
索引 Python
python之判断字符里面有没有|8
python之判断字符里面有没有|8
|
12月前
|
Python
[oeasy]python035_根据序号得到字符_chr函数_字符_character_
本文介绍了Python中的`ord()`和`chr()`函数。`ord()`函数通过字符找到对应的序号,而`chr()`函数则根据序号找到对应的字符。两者互为逆运算,可以相互转换。文章还探讨了单双引号在字符串中的作用,并解释了中文字符和emoji也有对应的序号。最后总结了`ord()`和`chr()`函数的特点,并提供了学习资源链接。
144 4
|
12月前
|
Python
Python ASCII码与字符相互转换
Python ASCII码与字符相互转换
|
数据采集 Python
|
Python
【Python】正则表达式判断是否存在连续相同的两个字符,连续两个字符一模一样
Python函数isContinuousChar,使用正则表达式来检测字符串中是否存在连续的相同字母或数字,并返回存在此类字符的列表长度,如果列表长度为0则表示不存在连续相同的字符。
389 2

热门文章

最新文章

推荐镜像

更多