Issue-3 字符串和编码,了解bytes str unicode的区别

在此之前,我们先简单了解一下编码。

因为计算机只能处理数字,如果要处理文本等,那么必须要把文本转化为二进制的数字才可以处理,最开始只有127个字符被编码计算机里,包括大小写字母,符号,数字,就是美国人用的这些就够了,这套编码表叫做ASCII编码,就是用一个字节编码一个字符,一个字节8位,但是后来呢,由于要加入各种语言,比如中文,日文,韩文等,就不够用了,中文需要用2个字节,所以中国就制订了GB2312规则,把中文加了进去,但是这样肯定不可以的,世界就不统一了,我们写好的文章放到其他国家的计算机里就乱码了呀,这样不行的。

于是,Unicode应运而生,它把所有语言统一到一套编码里,这样就不会有乱码问题了。ascii一个字节,Unicode通常2个字节,因为一些生僻字可能需要3或者4个字节

所以说Unicode编码也是一种编码规则,编码表。


再说一下我们写代码时通常前面会声明一下 UTF-8,这个UTF-8是啥?当我们用中文的时候,是用了2个字节,但是当你在unicode编码下用字母呢,其实只是用了一个字节,就是后面的一个字节,比如  00000000 01000000  ,大家会注意这里就造成了浪费,就是在原来的字节前面加0就可以了,这样就相当于多了一倍的储存空间,在存储和运输上不太划算。

于是,又出现了一个基于Unicode编码的可变长度的UTF-8编码,它把Unicode编码根据不同的数字大小编码成1-6个字节,常用的字母就是一个字节,汉字等通常2-3个字节,这里我们可以注意到,ASCII码其实是可以看成是UTF-8码的一部分,因为当传输英文数字时,长度也是一个字节,和ASCII一样的,这样,很多遗留的历史ASCII问题就可以用UTF-8编码解决了。


现在我们看一下计算机通用的字符编码工作模式:

在计算机内存中,用的是Unicode编码,当要存储在硬盘或者传输时,就转换为UTF-8模式,当我们在编辑一个文本文件时,还没保存的时候,我们用的就是Unicode编码,当我们点击保存时,这时候就转换为UTF-8编码了,当我们读取的时候,就又变成了Unicode编码,就是这样转换的。


在Python3中,字符串str就是以Unicode编码格式编码的,也就是说,Python的字符串可以包括多语言,比如 ‘asd’  和 ‘六角恐龙’  都是可以显示的,不会乱码。


Python提供 ord函数获取字符的整数表示,用char函数转换整数到字符格式   ord('A') = 65    char(65) = 'A'


python的字符串类型是str,在内存里以Unicode编码表示,当存储在硬盘时,就要转换为字节为单位的bites,Python对于bites类型的数据用带‘b‘前缀的单引号活双引号表示。


x = b'asd' 这是bite类型的数据,可以看下面的例子,


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

print ('asd'.encode('ascii'))
print(b'asd'.decode('ascii'))
print(b'asdsf'.decode('utf-8'))
#print('中'.encode('ascii'))   会报错,因为中文不能用ascii码来编码
print('中'.encode('utf-8'))

输出:


b'asd'
asd
asdsf
b'\xe4\xb8\xad'


所以我们在编写程序的时候,一定要把编码和解码放在界面的最外围来做,程序的核心部分应该使用Unicode编码来做,这种办法可以令程序可以接受多种类型的文本编码,并输出的时候只采用一种编码,就是UTF-8编码。

我们最好写2个辅助函数,以便在这两种情况下转换,是的转换后的数据能够符合我们的预期。


Python3 中,我们需要编写接受str或者bites,并只返回str或者bites的函数


只返回str;


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

def return_only_str(str_or_bytes):
    if isinstance(str_or_bytes,bytes):
        ret = str_or_bytes.decode('utf-8')
    else:
        ret = str_or_bytes
    return ret

print(type('asd'))
print(return_only_str('asd'))
print(type(b'asdasd'))
print(return_only_str(b'asdasd'))

输出:


<class 'str'>
asd
<class 'bytes'>
asdasd



只返回bytes:

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

def return_only_byte(str_or_bytes):
    if isinstance(str_or_bytes,str):
        ret = str_or_bytes.encode('utf-8')
    else:
        ret = str_or_bytes
    return ret

print(type('asd'))
print(return_only_byte('asd'))
print(type(b'asdasd'))
print(return_only_byte(b'asdasd'))

输出:

<class 'str'>
b'asd'
<class 'bytes'>
b'asdasd'


另外Python3还需要注意一个问题,就是当我们使用file函数,file open read等,都是从硬盘里来读文件的操作,我们之前说过的,数据是以二进制的bytes存储的。而Python3的open函数添加了名为encodeing的新参数,而这个新参数的默认值为utf-8,这样在文件句柄上进行write 和 read时,系统就要求开发者必须传入包含unocode的str实例,而不是二进制的bytes实例,这样就会发生错误,就是说我们在以str的格式向硬盘里写数据,这样是不行的,计算机是不认识的。

所以我们要这样来写

with open(file,'wb')  as f :   这里的b指的是以2进制的格式来写, 来读文件的时候也是一样的, ‘rb’





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值