新手玩王者需要知道的信息,新手玩王者需要知道的问题
转自:http://blog.csdn.net/a921800467b/article/details/8579510
为什么会报告错误“Unicode编码器:“ASCII”编解码器无法对位置0-1中的字符进行编码:序号不在范围(128)内”?本文将研究这一问题。
Python中字符串的表示是unicode编码。因此,在编码转换中,通常使用unicode作为中间编码,即先将其他编码的字符串解码成unicode,然后再编码成另一种编码。
decode的作用是把其他代码编码的字符串转换成unicode代码,比如str1.decode(gb2312 ),意思是把gb2312编码的字符串转换成unicode代码。
encode的作用是将unicode编码转换成其他编码字符串,比如str2.encode(gb2312 ),意思是将unicode编码字符串str2转换成gb2312编码。
所以在转码的时候,首先要了解字符串str是什么编码,然后解码成unicode,再编码成其他编码。
中代码字符串的默认编码与代码文件本身的编码一致。
例如s=中文
如果在utf8文件中,字符串是utf8代码,如果在gb2312文件中,其代码是gb2312。在这种情况下,为了执行编码转换,需要首先使用decode方法将其转换为unicode编码,然后使用encode方法将其转换为其他编码。通常,当没有指定特定的编码方法时,使用系统的默认编码来创建代码文件。
如果字符串是这样定义的:s=u 中文
字符串的编码被指定为unicode,即python的内部编码,与代码文件本身的编码无关。因此,在这种情况下,我们只需要直接使用encode方法将其转换为指定的代码。
如果一个字符串已经是unicode了,再解码就错了,所以通常需要判断它的编码方式是不是unicode:
is instance(s,unicode) #用于确定是否为unicode。
以非编码编码的形式用str编码会报错。
如何获取系统的默认代码?
#!/usr/nrdsh/env python
#编码=utf-8
导入系统
printsys.getdefaultencoding()
这个程序在英文WindowsXP上的输出是ascii。
这个程序在英文Windows7上的输出是:mbcs。
在某些IDE中,字符串的输出总是出现乱码甚至错误,这其实是由于IDE本身的结果输出控制台无法显示字符串的编码,而不是程序本身的问题。
例如,在UliPad中运行以下代码:
S=u 中文
打印s
是:unicode编码器错误:“ascii”编解码器无法对位置0-1中的字符进行编码:序号不在范围内(128)。这是因为英文WindowsXP上的UliPad的控制台信息输出窗口是按照ascii编码输出的(英文系统默认编码是ascii),而上面代码中的字符串是Unicode编码,所以输出有错误。
将最后一句改为:prints.encode(gb2312 )
可以正确输出单词“中文”。
如果最后一句改为:prints.encode(utf8 )
output:\ xe4 \ xb8 \ xad \ xe6 \ x96 \ x87,是控制台信息输出窗口根据ascii编码输出utf8编码字符串的结果。
Unicode(str, gb2312 )与str.decode(gb2312 )相同,它将gb2312编码的str转换为Unicode。
使用str。__class__查看str的编码形式。
groups . Google . com/group/python-cn/browse _ thread/thread/be 4 E4 e 0d 4c 3272 DD
-
Python是一种容易出现编码问题的语言。于是,我按照我的理解写了下面的话。
=首先要知道几个概念。=
*字节:计算机数据的表示。8位二进制。可以表示无符号整数:0-255。在下文中,“字节流”用于表示由“字节”组成的字符串。
*字符:英文字符“abc”,或中文字符“你、我、他”。人物本身不知道怎么保存在电脑里。在下文中,将避免使用“字符串”一词,而是使用“文本”。
显示一串“字符”。
*编码(动词):按照一定的规则(这个规则叫做:编码(名词)),“文本”转换成“字节流”。(在python中:unicode变成了str)
*解码(动词):按照一定的规则将“字节流”转换成“文本”。(在python中:str变成unicode)
* *实际上,计算机中表示的任何东西都需要编码。比如视频要编码然后保存在文件里,播放的时候需要解码才能观看。
Unicode:unicode定义了一个“字符”和一个“数字”之间的对应关系,但它没有指定这个“数字”是如何存储在计算机中的。(就像在C语言中一样,整数既是
它可以是int或short。Unicode没有指定是使用int还是short来表示“字符”)
Utf8:unicode实现。它使用unicode定义的“字符”和“数字”映射,然后指定如何在计算机中保存这个数字。其他utf16等。
Unicode实现。
Gbk:类似utf8的“代码”。但是,它不使用unicode定义的“字符”和“数字”映射,而是使用另一组映射方法。此外,它还定义了如何使用
保存在电脑里。
=python=中的编码、解码方法
首先要知道编码是unicode转换成str。Decode是str到unicode的转换。
在下面,u表示unicode类型的变量,s表示str类型的变量。
U.encode( . ))基本上总是成功的,只要你填写正确的代码。就像任何文件都可以压缩成zip文件一样。
S.decode( . )经常出错,因为“代码”str是什么要看上下文。硬棒棒糖解码的时候,需要确定用的是什么码S。比如,打开zip文本。
确保它确实是一个zip文件,而不仅仅是一个带有伪造扩展名的zip文件。
不推荐U.decode(),s.encode(),s.encode相当于s.decode()。默认情况下,encode()首先被编码(通常
Ascii)在编码中转换为unicode。
=关于#编码=utf8=
硬棒棒糖在py文件的第一行写了这句话,并且确实按照这段代码保存了文本,那么这句话就有以下作用。
1.让词法分析器正常工作,不要在评论里报错中文。
2.对于U Chinese 来说,literal string可以知道两个引号中的内容是utf8编码的,然后就可以正确的转换成unicode。
3.中文对于这样的literalstring,你会知道中间的内容是utf8代码,然后就可以正确的转换成其他代码或者unicode。
我还没写完,先码这么多字,以后再补充。这不是维基,太麻烦了。
=Python编码和Windows控制台=
我发现很多初学者在打印语句上犯了错误,这涉及到控制台的输出。我不懂linux,只说主机。
首先,Windows的控制台确实是unicode(utf16_le编码),或者更准确的说,是用字符输出文本。
但是程序的执行可以重定向到文件,文件的单位是“字节”。
所以对于C运行时的函数printf之类的,输出一定要有把文本转换成字节的代码。可能是为了兼容95,98,
没有unicode编码,只有mbcs(不是gbk之类的)。
windows的Mbcs,也就是ansi,在windows的不同语言中会使用不同的代码,在中文windows中是gb系列代码。
这会导致相同的文本,这在不同语言的windows中是不兼容的。
现在我们知道,如果要在windows的控制台中输出文本,其编码必须是“mbcs”。
对于python的unicode变量,如果使用打印输出,将使用sys.getfilesystemencoding()返回的代码将其转换为str。
如果是utf8编码的str变量,那么需要prints.decode (UTF8 )。编码(“MBCS”)
最后,str变量、文件读取的内容和urllib获取的网络上的内容都是“字节”的形式。
例如,如果它们确实是一个“文本”,你想把它打印出来看看。那你一定知道他们的密码。然后解码成unicode。
如何知道他们的代码:
1.提前做好约定。(例如,这个文本文件是您自己用utf8代码保存的)
2.协议。(# coding=python文件第一行的utf8,html中的meta等。)
2.猜猜看。
这个很好,但是还不是很清楚。
将“文本”转换为“字节流”。(在python中:unicode变成了str)
最后,str变量、文件读取的内容、urllib获取的网络上的内容都是“字节”的形式。
虽然文件或网页是文本,但它们在保存或传输时已经被编码成字节,所以用 rb 打开的文件和从socket读取的流是基于字节的。
例如,如果它们确实是一个“文本”,你想把它们打印出来看看。那你一定知道他们的密码。然后解码成unicode。
这里引用的“文本”实际上是一个字节流,而不是一个真实的文本(unicode),这只是意味着我们知道它可以被解码成文本。
解码时,如果是基于协议,可以直接从指定的地方读取指定的编码比如BOM或者python文件或者网页的meta,就可以正确解码。
不过,虽然很多文件/网页都被赋予了代码,但文件格式实际上使用了其他代码(比如py文件中指定了coding=utf8,但你还是可以保存为ansi - Notepad的默认代码)。在这种情况下,真正的代码需要猜测。
解码后的文本只存在于运行环境中。如果需要打印/保存/输出到数据库/网络进行传输,就需要另一个编码过程。这个编码和上面的编码无关,只看你的选择。但是这种编码并不是可选的,因为如果编码后的字节需要传输给其他人/环境,那么如果你的编码没有遵循契约,就会给下一个人/环境带来麻烦,所以会递归。
最主要的一点很容易让人误解:
人们普遍认为Unicode(广义)统一编码,其实不然。Unicode不是唯一的代码,而是很多代码的统称。但是Windows下的Unicode
(狭义)一般指UCS2,即UTF-16/LE
Unicode字符集(ucs)是唯一的,但是有许多编码方案(utf)。
区分字符和字节的概念很重要。Java一直是这样,Python也开始这样了,Ruby好像还在混乱中。
我也说句话吧。我对编码的研究比较深入。因为工作中经常遇到乱码,2005年,我对编码做了一个专题研究,并在公司刊物上发表了文章。最后我形成了一本教材,每年都给公司新员工讲。所以项目中的乱码问题可以快速定位并解决。
理论上,从一个字符到一个具体的代码,会经历以下几个概念。
字符集(抽象字符集)
编码字符集(编码字符集)
字符编码形式(字符编码形式)
字符编码方案(字符编码方案)
字符集:甚至是一堆抽象的字符,比如全是汉字。字符集的定义是抽象的,与计算机无关。
编码字符集:它是从整数集的子集到字符集的抽象元素的映射。也就是抽象字符数量。按照gb2312的定义,每个字符都有一个与之对应的整数。一个整数只对应一个字符。反之,也不一定。这里所说的映射关系是数学意义上的映射关系。编码字符集也是独立于计算机的。Unicode字符集也在这一层。
字符编码:这个和电脑有关系。编码字符集的编码点在计算机中的具体表示。通俗地说就是怎么把字符对应的整数放到电脑内存里,或者文件里,或者网络里。所以不同的人有不同的实现方式。所谓驰骋千码,指的就是这个。Gb2312、utf-8、utf-16、utf-32等。都在这一层。
字符编码方案:这个和计算机关系更密切。它与操作系统密切相关。主要解决大小字节顺序的问题。对于UTF-16和UTF-32
编码,Unicode都支持大端和小端编码方案。
一般来说,我们所说的编码是在第三层完成的。具体到一个软件系统,是很复杂的。
浏览器- apache-tomcat(包括tomcat中的jsp编码、编译和文件读取)-只要数据库之间有数据交互,就可能存在编码不一致的情况。如果在读取数据时没有正确的解码和编码,出现乱码是很常见的。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。