python中字符串编码形式及其所占字节

1.常见字符串编码错误

在使用Python读文件时经常遇到编码问题引起的错误,比如:

UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 30: illegal multibyte sequence

遇到这种异常时可以通过读文件时规定编码方式来解决,如下:

with open('zhengfu.txt','r',encoding='UTF-8') as read_zhengfu:

如果文件中还包含其他非UTF-8编码的字符,或者无关的特殊字符,可以再加入一个参数,如下:

with open('zhengfu.txt','r',encoding='UTF-8',errors='ignore') as read_zhengfu:

有时读文件时还会遇到一种问题就是第一行数据的开头多了一串‘'\ufeff’字符。比如:

如果用print(list[0])是看不到这个字符的。对这个没有研究过, 如果要去掉这串字符的话,可以使用‘utf-8-sig’这种编码方式:

with open('user_dict_2.txt','r',encoding='utf-8-sig') as read_dict:

但是我在写入文件时设置为‘utf-8-sig’格式时不起作用,写入的文件中还是有这个字符。

另外,在对字符串进行匹配的时候,'\ufeff’会影响字符串的匹配结果。

2.字符串编码

关于计算机内部如何表示字符串,为何又要创造这么多种编码方式,推荐阅读 https://www.cnblogs.com/hhwu/p/9529942.html 这篇博客里作者讲的很明白,这里主要是想汇总介绍Python中的字符串函数。

2.1 chr()函数和ord()函数

chr()函数是将一个整数返回一个对应的字符,ord()函数则相反,其返回一个字符的数值表示(返回的是Unicode值的十进制表示)。在Python3.6的版本中,chr()中整数的范围不再是0到255,扩大到了1114111,大于改值时,报ValueError错误。而ord()函数中只能接受单字符串作为其输入,否则会报TypeError错误。

print(chr(65)) #输出'A'
print(ord('A')) #输出65

2.2 Unicode编码

虽然Python 3的内存中Unicode来保存字符串,但为了节省内存,Python3内部使用3种方式存储Unicode字符。具体分为以下三种:

Latin-1一个字符占一个字节。比如ASCII码值
UCS-2一个字符占两个字节。常见的中文都占用2个字节
UCS-4一个字符占四个字节。比较偏僻的中文还有emoj表情通常占用4个字节。

python中提供了内置函数来查看每个字符串对象的编码类型。如果一个字符串的所有字符都能用ASCII码来表示,那么该字符串使用Latin-1。如果字符串中出现了中文,则采用UCS-2编码即可。如果字符串中有一些生僻字或者emoj表情的话,则必须使用UCS-4编码。注意在Python中,一个字符串中的所有字符只能采用一种编码方式,不能混用。因为一旦混用,那么字符串中每个字符所占的字节数必定不同,那么字符串将不能使用下标进行快速直接读取。下面来具体看看字符串具体在内存中所占用的字节数。

字符串的长度和该字符串所占的字节数不相同。字符串的长度可以直接通过len()f方法来求,而字符串在内存中实际所占的字节数需要通过getsizeof()函数来计算。

import sys
#返回字符串所占字节数,返回78
print(sys.getsizeof('你好'))
#返回字符串长度,长度为2
print(len("你好"))

从以下的实验结果可以发现,一个空字符串在内存中就占了49个字节的内存。

Python内存中的数据,不管是int型还是字符串,都会额外占用一些内存空间保存一些信息,这些信息保存了字符串的一些基础信息,并且能够决定字符串所能进行的操作。Python一般会为字符串分配49到80个字节的额外空间。

下面这段代码分别展示了字符‘a’在三种不用的Unicode编码中所占的字节数。

import sys
#latin-1编码时'a'所占的字节数,其结果为:1
print(sys.getsizeof('ab')-sys.getsizeof('b'))
#ucs-2编码时'a'所占的字节数,其结果为:2
print(sys.getsizeof('a你好')-sys.getsizeof('你好'))
#ucs-4编码时'a'所占的字节数,其结果为:4
print(sys.getsizeof('a?')-sys.getsizeof('?'))

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值