知行编程网知行编程网  2022-12-16 10:00 知行编程网 隐藏边栏  10 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于Python编码处理之 str与Unicode的区别与使用的相关知识,希望可以帮到处于编程学习途中的小伙伴

Python编码处理中str和Unicode的区别和使用

在使用python处理中文的时候,在读取文件或者消息的时候,如果发现乱码(字符串处理,读写文件,打印),大部分人都会调用encode/decode进行调试,而没有想清楚为什么会出现乱码。今天我们来讨论一下如何处理编码问题。


调试时最常出现的错误

错误1

Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: ‘ascii‘ 
codec can‘t 
decode byte 0xe6 in position 0: ordinal not in range(128)

错误2

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/
Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode     return 
codecs.utf_8_decode
(input, errors, True) UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in position 0-1: 
ordinal not in 
range(128)


首先

必须有大体概念,了解下字符集,字符编码

ASCII | Unicode | UTF-8 | 等等

字符编码笔记:ASCII,Unicode和UTF-8

str 和 unicode

str和unicode都是basestring的子类

所以有判断是否是字符串的方法

def is_str(s): return isinstance(s, basestring)

str和unicode 转换

str -> decode(‘the_coding_of_str‘) -> unicode unicode -> encode(‘the_coding_you_want‘) -> str


区别

str是字节串,由unicode经过编码(encode)后的字节组成的

声明方式

>>> s = ‘中文‘ s = u‘中文‘.encode(‘utf-8‘)  
>>> type(‘中文‘) <type ‘str‘>

求长度(返回字节数)

>>> u‘中文‘.encode(‘utf-8‘) ‘\xe4\xb8\xad\xe6\x96\x87‘ 
>>> len(u‘中文‘.encode(‘utf-8‘))


结论

搞明白要处理的是str还是unicode, 使用对的处理方法(str.decode/unicode.encode)

下面是判断是否为unicode/str的方法

>>> isinstance(u‘中文‘, unicode) True 
>>> isinstance(‘中文‘, unicode) False  
>>> isinstance(‘中文‘, str) True 
>>> isinstance(u‘中文‘, str) False

简单原则:str不要用encode,unicode不要用decode(其实可以对str进行encode,详见文末,为保证简单,不推荐)

>>> ‘中文‘.encode(‘utf-8‘) 
Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeDecodeError: ‘ascii‘ 
codec 
can‘t decode byte 0xe4 in position 0: ordinal not in range(128)  
>>> u‘中文‘.decode(‘utf-8‘) 
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/
Python.framework/Versions/2.7/lib/python2.7/encodings/utf_8.py", line 16, in decode     return 
codecs.utf_8_decode(input, errors, True) UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in 
position 
0-1: ordinal not in range(128)

不同编码转换,使用unicode作为中间编码

#s是code_A的str s.decode(‘code_A‘).encode(‘code_B‘)

文件处理,IDE和控制台

处理流程可以这样使用。把 python 想象成一个游泳池、一个入口和一个出口

入口处全部转成unicode,pool里的全部用unicode处理,出口处转成目标码(当然也有例外,处理逻辑中用到具体的code)

读取文件外部输入代码,解码为unicode处理(内码,统一unicode)编码为需要的目标代码,写入目标输出(文件或控制台)

IDE和控制台报错,原因是打印的时候编码和IDE自己的编码不一致。

输出时将编码转换成一致的就可以正常输出

>>> print u‘中文‘.encode(‘gbk‘) ???? 
>>> print u‘中文‘.encode(‘utf-8‘) 中文


建议

规范编码

统一编码,防止由于某个环节产生的乱码

环境编码、IDE/文本编辑器、文件编码、数据库数据表编码

保证代码源文件编码

这个很重要

py文件的默认编码是ASCII。源代码文件中,如果使用非ASCII字符,需要在文件头部做编码声明Documentation

如果不声明,输入非ASCII时遇到的错误必须放在文件的第一行或第二行

File "XXX.py", line 3 SyntaxError: Non-ASCII character ‘\xd6‘ in file c.py on line 3, but no encoding declared; 
see http://www.python.org/peps/pep-0263.html for details


声明方法

# -*- coding: utf-8 -*- 或者 #coding=utf-8

若头部声明coding=utf-8, a = ‘中文‘ 其编码为utf-8

若头部声明coding=gb2312, a = ‘中文‘ 其编码为gbk

所以,同一个项目中的所有源文件头都有统一的编码,声明的编码必须和源文件中保存的编码一致(编辑器相关)

在源代码用作处理的硬编码字符串,统一用unicode

将其类型与源文件本身的编码隔离开来,独立独立,方便在流程中的各个位置进行处理

if s == u‘中文‘:  #而不是 s == ‘中文‘     pass #注意这里 s到这里时,确保转为unicode

完成以上步骤后,你只需要注意这两个unicode和你设置的编码即可(一般使用utf-8)


处理顺序

1. Decode early 2. Unicode everywhere 3. Encode later

相关模块及一些方法

获得和设置系统默认编码

>>> import sys 
>>> sys.getdefaultencoding() ‘ascii‘  
>>> reload(sys) <module ‘sys‘ (built-in)> 
>>> sys.setdefaultencoding(‘utf-8‘) 
>>> sys.getdefaultencoding() ‘utf-8‘ 
>>> str.encode(‘other_coding‘)

在python中,直接将某种编码的str进行encode成另一种编码str

#str_A为utf-8 str_A.encode(‘gbk‘) 执行的操作是 str_A.decode(‘sys_codec‘).encode(‘gbk‘) 这里sys_codec即为上一步 sys.getdefaultencoding() 的编码

'获取和设置系统默认编码'在这里和str.encode相关,但是我很少这么用,主要是比较复杂,不可控。输入清晰的解码和输出清晰的编码更容易

chardet


文件编码检测,下载

>>> import chardet 
>>> f = open(‘test.txt‘,‘r‘) 
>>> result = chardet.detect(f.read()) 
>>> result {‘confidence‘: 0.99, ‘encoding‘: ‘utf-8‘}

\u字符串转对应unicode字符串

>>> u‘中‘ u‘\u4e2d‘  
>>> s = ‘\u4e2d‘ 
>>> print s.decode(‘unicode_escape‘) 中  
>>> a = ‘\\u4fee\\u6539\\u8282\\u70b9\\u72b6\\u6001\\u6210\\u529f‘ 
>>> a.decode(‘unicode_escape‘) u‘\u4fee\u6539\u8282\u70b9\u72b6\u6001\u6210\u529f‘

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享