python字符串编码_Python字符串编码答疑

Python 2中的字符串分类

在Python 2中字符串,有两个类型,一个是str,一个是unicode。str可以理解为ASCII的字符列表,说白了,只能存储ASCII字符,如果赋个中文值,会报错;而unicode是支持非ASCII字符的。这个与C语言中的字符非常类似char[]只能存ASCII字符串,而wchar[]才可以存储Unidcode字符串。

可以用如下方式来安全的转换两种字符串:

1

2

3

4

5

6

7

8

9

10

11def to_str(foo):if foo instanceof unicode:return str(foo)else:return foodef to_unicode(bar):if bar instanceof str:return unicode(bar)else:return bar

对于字面字符串,前面加上u来标识是一个unicode,否则会当成str:

1

2a = 'this is a string'b = u'nah, I am a unicode'

Python 3中的字符串分类

由于Python 2中的混乱,所以到了Python 3里面,有了新的定义,字符串类型是str,支持Unicode,另外多了一个类型bytes,可以理解为byte的列表,也即是0<=且<=256的无符号整数,或者说是ASCII字符,简单来理解意思是一样的。这个就与Java语言类似了,如同Java中一样,String支持unicode,另专门有byte类型。另外,对于字面字符串也无需要再要标识了。

str与bytes之间的关系与区别是,str是给人看的,而bytes是给机器看的,bytes是str的底层实现。所以,bytes处理起来更快,效率更高,一些底层的IO库以及像网络IO,用的数据 一般都是bytes。它们之间是可以互转的:

str转为bytes叫encode

bytes转为str叫decode

在转换的时候还需要指定编码格式,这个编码格式就是unicode的编码方式,默认是’utf-8’,这里就涉及Unicode编码解码的相关知识了,常见的就是’utf-8’,’unicode’,以及’gbk’等。可以用如下方法来安全的转换:

1

2

3

4

5

6

7

8

9

10def to_bytes(foo):if foo instanceof str:return foo.encode()else:return foodef to_str(bar):if bar intanceof bytes:return bar.decode()else:return bar

注意区分两个编码格式

需要注意区分两个编码格式的设置,一个是指定程序里面字符串的编码,如在encode()和decode()时指定编码格式。

另外,一个就是程序源文件的编码格式,这个容易被忽略,要详细说下:程序的源码,其实就是一个文本文件,对吧,那么这个文本文件也是要指定编码格式的,常规来说,Python程序应该都是ASCII字符,所以默认的呢Python解释器,是按照ASCII文本的方式来处理代码源文件,但我们代码里面是会出现Unicode字符的,比如字面字符串,或者写的注释,如果 不进行特殊的设置解释器会报错的,因为出现了它不认识的字符。这时就需要对源码文件设置一下编码格式,把这句加在代码源文件的最上面,就好了:

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

如何解决未知编码格式

关于编码最容易遇到的就是UnicodeDecodeError,后面跟着一坨详细信息,这个错误就是告诉你编码时出问题了,通常有两类错误:

UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xe4 in position 0: ordinal not in range(128)

这个通常是在Python 2时会遇到,原因简单的来说就是把unicode当成了string,或者源码文件的编码格式不对。解决的办法就是按照 上面介绍的安全转换方法,另外要设置一下源码文件的编码格式,这个问题自然可解。

Python3.6 UnicodeDecodeError: ‘utf8’ codec can’t decode byte 0xb2 in position 24137: invalid start byte

这个通常是在Python 3时面遇到的,后面的具体信息会不一样,这个问题会发生在bytes转化为string,decode时会报出,原因就是指定的解码方式与真实的不匹配,无法成功decode,比如,bytes是「gtk」的,但是用’utf-8’去decode肯定会失败。这个问题,在写爬虫或者一些文本处理时经常遇到,因为来源的编码方式不固定。

这个问题,如果想要根解,必须预知来源bytes的编码格式,但这通常不可能,所以可行的一条方案是,用一坨编码方式来不停的尝试:

def safe_decode(source):

encodeings = ['utf-8', 'gbk', 'utf-16']

for en in encodeings:

try:

return source.decode(en)

except UnicodeDecodeError as e:

print('Failed: ', e)

return source

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值