关于Python的编码问题
将GB2312中文字符解码
s = gb2312string.decode(‘gbk’)
将字符串转码为utf-8
s.encode(‘utf-8’)
查看解释器默认字符编码
import sys
sys.getdefaultencoding() # ascii
修改默认编码(本次)
reload(sys) # 解决报错问题
sys.setdefaultencoding('utf8’)
chstring = "中文字符"
with open('test.txt','w') as f:
... f.write(chstring)
...
mystring = chstring.encode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 0: ordinal not in range(128)
问题:
1, string.decode('gbk') 解码后的编码格式?(操作系统默认)
2, 环境默认ascii环境下输入的中文字符, open(filename, 'w')可以正常写入, 而'中文字符'.encode('ascii')报错,所生成文件的编码格式是什么?怎么确定的?
1
roricon 2015-01-11 17:17:41 +08:00 1
这个问题在py2和py3中的回答是不同的。
但一般只有在py2中才会踩到坑,那我就给个py2的答案吧。 1. 解码后的类型是 <unicode>,在写入file中的时候,会默认以<utf-8>来保存。 2.见问题1,'中文字符'.encode 肯定会失败 见下面这段 ========== In [8]: a = '你好' In [9]: a Out[9]: '\xe4\xbd\xa0\xe5\xa5\xbd' In [10]: type(a) Out[10]: str In [11]: a.decode('utf-8') Out[11]: u'\u4f60\u597d' In [13]: print(a.decode('utf-8')) 你好 ========== 实际上如果给一个中文字字符串<str>类型,实际上等同于如下步骤。 a = u'你好' a = a.encode('utf-8') 不知道这么说是否已经说明白了。 |
2
9hills 2015-01-11 17:36:49 +08:00 2
再次重复在我在多个地方阐述过的话:
Python2 没有任何必要使用 sys.setdefaultencoding('utf8’)。 其他两个问题,你只需要知道 encode是Unicode -> xxx ,decode是 xxx -> Unicode 就好了。。 |
3
zhicheng 2015-01-11 18:59:35 +08:00 2
1,和具体的 codec 有关系,例子中的 gbk 如果用在 str 上应该会返回 unicode 类型,用在 unicode 上应该还是 unicode 。
2,'中文字符'.encode('ascii') 这个是因为 ascii 这个 codec 无法处理 '中文字符' 这个 str 。 所有的 encode 和 decode 都和具体的 codec 有关系,返回的结果即可以是 str 也可以是 unicode 。 比如 'abcd'.encode('hex') 结果还是 str 。 多看看文档。 https://docs.python.org/2/library/codecs.html |
5
Sylv 2015-01-11 19:41:45 +08:00 via iPhone
@zhicheng 返回的结果即可以是 str 也可以是 unicode?不对吧。
应该是: str.decode() -> unicode unicode.encode() -> str str.encode() -> str.decode().encode() -> str unicode.decode() -> unicode.encode().decode() -> unicode |
8
Sylv 2015-01-11 20:02:53 +08:00 1
@loading 不同报错要视情况解决的。
基本思路是:任何可能是非 ascii 的 str 输入要 decode('utf-8') 为 unicode,内部处理时都用 unicode,要输出时或使用不支持 unicode 的方法时(例如 urllib.unquote)再 encode('utf-8') 为 str。 |
9
hahastudio 2015-01-11 20:03:56 +08:00 1
|
11
Sylv 2015-01-11 21:28:00 +08:00 via iPhone
@zhicheng
Codec.encode(input[, errors]) Encodes the object input and returns a tuple (output object, length consumed). While codecs are not restricted to use with Unicode, in a Unicode context, encoding converts a Unicode object to a plain string using a particular character set encoding (e.g., cp1252 or iso-8859-1). Codec.decode(input[, errors]) Decodes the object input and returns a tuple (output object, length consumed). In a Unicode context, decoding converts a plain string encoded using a particular character set encoding to a Unicode object. https://docs.python.org/2/library/codecs.html |
13
013231 2015-01-11 22:14:09 +08:00
回答:
1. str decode后得到的是unicode类型. unicode类型是对字符的抽象, 你无须关心它内部使用编码方式(可能是UCS-2或UCS-4, 编译时指定). 2. interpreter里输入的文字, 编码方式由sys.stdin.encoding确定. ASCII不能编码汉字, 所以会报错. |
14
Sylv 2015-01-11 22:15:47 +08:00
|
15
013231 2015-01-11 22:17:32 +08:00
PS: str是字节组, 对它encode没有意义.
str解码(decode)后得到unicode, unicode编码(encode)后得到str. |
16
Sylv 2015-01-11 22:31:43 +08:00
@zhicheng 我明白你的意思了,你指的是 hex 等非 Unicode 相关的 codecs。我说的是楼主这种处理 Unicode 的情况。受教了。
|
17
zhicheng 2015-01-11 22:33:18 +08:00 1
|