Python学习笔记--字符串与bytes

本文介绍了Python中字符串(string)和字节(bytes)的区别,包括它们的定义、编码方式以及为什么需要编码。字符串是文本序列,用utf8等编码表示字符;字节是无编码的字节序列。编码过程是将信息从一种形式转换为另一种,Python3中字符串默认utf8编码。此外,还讨论了bytes类型及其可变版本bytearray,以及它们在图像处理等场景中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义

  • string是文本序列
  • bytes是字节序列

区别

  • 文本是有编码的,例如:utf8,gbk,GB18030等
  • 字节没有编码
  • 文本的编码指的是字符如何使用字节来表示

编码

  • 单字节编码,例如:ascii
  • 多字节编码,例如:utf8

编码是信息从一种形式或格式转换为另一种形式的过程,也称为计算机编码语言的代码,简称编码。python3中,字符串默认使用utf8编码
bytes:字符串经过编码后的数据类型。

用utf8编码表示的字节如下:

>>> s = '人人都会有迷茫不知所措的时候'
>>> type(s)
<class 'str'>
>>> s.encode()
b'\xe4\xba\xba\xe4\xba\xba\xe9\x83\xbd\xe4\xbc\x9a\xe6\x9c\x89\xe8\xbf\xb7\xe8\x8c\xab\xe4\xb8\x8d\xe7\x9f\xa5\xe6\x89\x80\xe6\x8e\xaa\xe7\x9a\x84\xe6\x97\xb6\xe5\x80\x
99'

每个字符有3个字节(3个16进制数组成)
‘人’的utf8字节为:b'\xe4\xba\xba

再来看下十六进制数转换成十进制数的例子:

>>> 0x23
35
>>> 0xe4
228
>>> 0x3a
58
#转成二进制
>>> bin(0x23)
'0b100011'
>>> bin(0xe4)
'0b11100100'
#0b代表这个数是二进制

我们也可以encode其它字节:

>>> s = '人人都会有迷茫不知所措的时候'
>>> s.encode('gbk')
b'\xc8\xcb\xc8\xcb\xb6\xbc\xbb\xe1\xd3\xd0\xc3\xd4\xc3\xa3\xb2\xbb\xd6\xaa\xcb\xf9\xb4\xeb\xb5\xc4\xca\xb1\xba\xf2'
#gbk编码出来的与utf8出来的字节不一样
#计算机中均是如此表示的,不单单是python如此

bytes是可以转换成字符串的

>>> b = s.encode('gbk')
>>> b.decode('gbk')
'人人都会有迷茫不知所措的时候'
>>> b = s.encode()
>>> b.decode()
'人人都会有迷茫不知所措的时候'

事实上,转换可能会出现乱码,而乱码是没法转化的。
gbk是双字节,而utf8是三字节,所以会产生不对应。通常来说,绝大部分中文都是utf8三字节。unicode都是固定字节编码的,UTF-8用1到4个字节编码Unicode字符。

为什么要用编码?

因为我们现在的应用都是跨网络的。比如:

  • 服务器是linux utf8
  • 客户端时windows gbk
  • 通过socket通信

当客户端发送了一个gbk字符串给linux服务器,linux就需要转码,否则就会乱掉。客户端默认为gbk,服务端用decode utf8就会失败,故需要做约定,gbk为gbk,然后用decode gbk解码,不能突然变成utf8。
因此在python3中,socket只能用bytes
(python2是不区分bytes和string的。)

bytes

  1. bytes的定义
    string的所有操作,bytes都支持

     bytes由str通过encode方法转化得到
     通过b前缀定义bytes
    

b前缀如下:

>>> bt = b'\xe4\xba\xba'
>>> type(bt)
<class 'bytes'>
>>> bt2 = b'abc'
>>> type(bt2)
<class 'bytes'>

  1. bytes的操作
    bytes的方法
    bytes的方法里绝大多数都是string的方法
    bytes的操作除了encode外,str操作都有对于bytes的版本,但是传入参数也必须是bytes,如果传入字符串会报错

bytes的操作是按字节来的:

>>> s = '人人都会有迷茫不知所措的时候'
>>> s.encode()
b'\xe4\xba\xba\xe4\xba\xba\xe9\x83\xbd\xe4\xbc\x9a\xe6\x9c\x89\xe8\xbf\xb7\xe8\x8c\xab\xe4\xb8\x8d\xe7\x9f\xa5\xe6\x89\x80\xe6\x8e\xaa\xe7\x9a\x84\xe6\x97\xb6\xe5\x80\x
99'
>>> s.encode().find(b'\xe4')
0
#长度也是按照字节来计算的:
>>> len(s.encode())
42
#bytes.decode()转化为str,bytes.hex()转化为16进制:
>>> bt = b'\xe4\xba\xba'
>>> bt.decode()
'人'
>>> bt.hex()
'e4baba'

bytearray

  1. bytearray的定义
    bytearray是bytes的可变版本,str和bytes是不可变的
>>> bt = '人人都会有迷茫不知所措的时候'.encode()
>>> bt[0]
228
>>> bt2 = b'abc'
>>> bt2[1]
98
#将bytes转化为bytearray:
>>> ba = bytearray(bt)
>>> ba
bytearray(b'\xe4\xba\xba\xe4\xba\xba\xe9\x83\xbd\xe4\xbc\x9a\xe6\x9c\x89\xe8\xbf\xb7\xe8\x8c\xab\xe4\xb8\x8d\xe7\x9f\xa5\xe6\x89\x80\xe6\x8e\xaa\xe7\x9a\x84\xe6\x97\xb6
\xe5\x80\x99')
>>> type(ba)
<class 'bytearray'>
  1. bytes不可变&bytearray可变

bytes的时候是不可以赋值的:

>>> bt[0] = b'a'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment

但是bytearray是可变类型:

>>> ba = bytearray(b'abc')
>>> ba[0] = int(b'D'.hex(),16)
>>> ba
bytearray(b'Dbc')
  • bytearray更新的时候,也是一个一个字节更新的,不是一个字符串
  • 要把字节转换成十六进制数进行更替
  1. 使用场景
    有一种数据处理叫:图像处理
    当需要修改图片时,图片保存成了字节,bytes不可变,当一个图片修改一处就是3M,修改100处就是300M,对于图片的像素级修改,内存占用量如此高时不可行的,故而需要一个可变版本的bytes。

  2. bytearray的方法
    相对bytes来说,多了insert,append,extend,pop,remove,clear,reserver。其实就是多出了list的那些方法,并且可以索引操作。
    但和修改bytearray一样,所有的方法中,都需要用int来表示,而非bytes本身:

>>> ba.insert(int(b'E'.hex(),16),0)
>>> ba
bytearray(b'Dbc\x00')
>>> ba.append(20)
>>> ba
bytearray(b'Dbc\x00\x14')

int必须在0~256这个范围内,即8为的无符号整数

小结

学习了字符串和bytes,以及bytes的可变类型bytearray。
在经过前面的学习之后发现后面的也会比较能理解,果然学习都是一步一步的脚印额。虽然还是或多或少不熟悉的地方,再经过几遍练习就好了吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值