深入浅析python3中的unicode和bytes问题

作者:虞大胆 时间:2022-11-29 02:41:47 

最近写了一些python3程序,四处能看到bytes类型,而它并不存在于python2中,这也是python3和python2显著区别之一。

以前在写python2代码的时候,经常会遇到很多编码报错的异常,原因在于python2对unicode的支持不是特别理想。而在python3中,所有编写的代码都是unicode,python解析器在运行的时候,内部都转换(除非你显示定义为bytes类型)为unicode,减少了出错的可能性。

在python3中,有两种字符串类型,默认的就是str,即unicode,也叫做文本类型。但一个程序总是会有I/O操作(磁盘,网络),即I/O二进制数据,在python3中定义为bytes类型。bytes类型就是一个个字节串,包含0~256 之间的一个整数。

那么如何定义bytes类型呢,有两种显示的方法,比如:


#只能允许ASCII值
x=b'abc'
y=b'\xe6\x88\x91'
print (x,y)
#对unicode字符集进行特定编码
t=bytes("我们","UTF-8")
#输出b'\xe6\x88\x91\xe4\xbb\xac'
#一个中文字符,UTF-8编码占用三个字节
print (t)
#返回6,对于python来说,就是字节序列的长度
print (len(t))
#返回2,代表两个字符
print (len("我们"))

接下去说说str类型和bytes类型之间的转换,比如从网络上读取到二进制数据后,python需要你显示的将其转换为str类型,也就是说 python不会隐式在str和bytes之间转换 ,看上去麻烦了很多,但会减少你出错的几率,自己明确自己做要的事情。

如果要将str转换为bytes,必须选择一个编码,明确二进制数据是如何编码的,比如:


x="我"
y=x.encode("UTF-8")
z=x.encode("GBK")
#b'\xe6\x88\x91' b'\xce\xd2'
print (y,z)

如果要将bytes转换为str,也需要一个编码,必须说明的是,你必须知道 二进制数据的编码是什么 ,如果选错了,转换为unicode的时候会错误,另外在python内部,它不关心二进制数据是什么编码的,只要是bytes类型, 它就是一串字节序列 ,比如:


x=b'\xe6\x88\x91'
print (x.decode("UTF-8"))
#会报错
print (x.decode("GBK"))

总之一句话,“ python内部使用unicode,外部使用bytes类型 ”,python内建库中,很多函数会说明需要str类型还是bytes类型(严格说来是bytes-like对象,比如bytes、bytearray ),在写代码的时候一定要看清楚,比如 hamc 库的new方法,就要求:


hmac.new(key, msg=None, digestmod=None) key is a bytes or bytearray object giving the secret key

很多库,尤其第三方库(比如requests)为了兼容python2和python3,会在内部做很多转换工作,让你意识不到bytes类型的存在,虽然生产力提高了,但对于理解python并没有太大的好处。

如果要充分理解bytes和str的应用,可以参考open和write两个内建函数。

使用文本方式打开文件,python在内部会自动转换为str类型,比如:


file ="t.txt"
t = open(file,mode="r").read()

而如果是二进制方式打开,如果要显示在终端,需要转换为str类型,比如:


file ="t.txt"
t = open(file,mode="rb").read()
print (t.decode())
print (t,type(t))

而如果是二进制方式写入,则将bytes类型数据直接写入,比如:


file="t.txt"
t=open(file,mode="wb")
t.write(b'\xe6\x88\x91')

在上面几个例子中,都没有说明使用那种编码,如果不显示指定,一般编码等同于locale.getpreferedencoding()

总结

以上所述是小编给大家介绍的python3中的unicode和bytes问题,网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

来源:https://mp.weixin.qq.com/s

标签:python3,unicode,bytes
0
投稿

猜你喜欢

  • PHP面向对象继承用法详解(优化与减少代码重复)

    2023-11-21 10:16:48
  • Python异常与错误处理详细讲解

    2022-07-07 05:13:38
  • 解决Django响应JsonResponse返回json格式数据报错问题

    2022-12-07 00:06:02
  • Django Session和Cookie分别实现记住用户登录状态操作

    2021-09-14 05:15:24
  • antd table按表格里的日期去排序操作

    2024-04-28 10:55:56
  • vuecli3.0脚手架搭建及不同的打包环境配置vue.config.js的详细过程

    2024-04-30 08:42:13
  • sql server如何利用开窗函数over()进行分组统计

    2024-01-16 01:55:36
  • go语言编程之select信道处理示例详解

    2024-04-26 17:16:14
  • 详解在OpenCV中如何使用图像像素

    2022-05-04 16:05:08
  • Window10上Tensorflow的安装(CPU和GPU版本)

    2021-05-13 19:18:37
  • SQL Server 作业的备份(备份作业非备份数据库)

    2012-07-11 15:58:49
  • Golang学习之平滑重启

    2024-04-25 15:05:57
  • JavaScript中的Promise使用详解

    2024-04-18 10:53:52
  • PHP 简单日历实现代码

    2023-07-01 12:00:01
  • Access保留字和变量名列表

    2007-10-15 12:43:00
  • Python中实现输入一个整数的案例

    2022-05-28 18:42:21
  • 讲解数据库加密技术的功能特性与实现方法

    2008-12-18 14:24:00
  • SQLServer中字符串左对齐或右对齐显示的sql语句

    2012-06-06 19:36:45
  • python带你探寻WSGI Application原理

    2022-03-25 19:35:55
  • python爱心表白 每天都是浪漫七夕!

    2023-02-26 20:36:55
  • asp之家 网络编程 m.aspxhome.com