gpt4 book ai didi

Effective Python bytes 与 str 的区别

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 24 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Effective Python bytes 与 str 的区别由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

1、Python 有两种类型可以表示字符序列

  • bytes:实例包含的是 原始数据 ,即 8 位的无符号值(通常按照 ASCII 编码 标准来显示)
  • str:实例包含的是 Unicode 码点(code point,也叫作代码点),这些码点与人类语言之中的文本字符相对应
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a = b 'h\x6511o'
print ( list (a))
print (a)
 
a = 'a\\u300 propos'
print ( list (a))
print (a)
 
 
# 输出结果
[ 104 , 101 , 49 , 49 , 111 ]
b 'he11o'
 
[ 'a' , '\\', ' u ', ' 3 ', ' 0 ', ' 0 ', ' ', ' p ', ' r ', ' o ', ' p ', ' o ', ' s']
a\u300 propos

2、Unicode 数据和二进制数据转换

  • 把  Unicode 数据转换成二进制数据,必须调用 str 的 encode 方法(编码)
  • 把二进制数据转换成 Unicode 数据,必须调用 bytes 的 decode 方法(解码)
  • 调用这些方法时,可以明确指出字符集编码,也可以采用系统默认的方案,通常是 UTF-8

3、使用原始的 8 位值与 Unicode 字符串

使用原始的 8 位值与 Unicode 字符串时需要注意的两个问题:

  • 该问题等价于:使用 bytes str 时需要注意的两个问题

3.1 问题一:bytes 和 str 的实例互不兼容

使用 + 操作符:

?
1
2
3
4
5
6
7
8
9
10
# bytes+bytes
print (b 'a' + b '1' )
 
# str+str
print ( 'b' + '2' )
 
 
# 输出结果
b 'a1'
b2
  • bytes + bytesstr + str 都是允许的
  • bytes + str 会报错

# 。

?
1
2
3
4
5
6
7
bytes + str
print ( 'c' + b '2' )
 
 
# 输出结果
print ( 'c' + b '2' )
TypeError: can only concatenate str ( not "bytes" ) to str

同类型之间也可以用二元操作符来比较大小 。

?
1
2
3
assert b 'c' > b 'a'
 
assert 'c' > 'a'

但 bytes 和 str 之间用二元操作符也会报错 。

?
1
2
3
4
5
6
assert b 'c' > 'a'
 
 
# 输出结果
     assert b 'c' > 'a'
TypeError: '>' not supported between instances of 'bytes' and 'str'

判断 bytes 与 str 实例是否相等 两个类型的实例相比较总会为 False,即使字符完全相同 。

?
1
2
3
4
5
6
# 判断 str、bytes
print ( 'a' = = b 'a' )
 
 
# 输出结果
False

格式化字符串中的 %s 。

两种类型的实例都可以出现在 % 操作符的右侧,用来替换左侧那个格式字符串(format string)里面的 %s 。

但是!如果格式字符串是 bytes 类型,那么 不能 用 str 实例来替换其中的 %s ,因为 Python 不知道这个 str 应该按照什么字符集来编码 。

?
1
2
3
4
5
6
7
# %
print (b 'red %s' % 'blue' )
 
 
# 输出结果
     print (b 'red %s' % 'blue' )
TypeError: % b requires a bytes - like object , or an object that implements __bytes__, not 'str'

但是!反过来却可以,如果格式字符串是 str 类型,则 可以 用bytes 实例来替换其中的 %s,但结果可能不是预期结果 。

?
1
2
3
4
5
6
# %
print ( 'red %s' % b 'blue' )
 
 
# 输出结果
red b 'blue'

这样会让系统在 bytes 实例上面调用  __repr__  方法 调用结果替换格式字符串里的 %s,因此程序会直接输出 b'blue',而不是输出 blue 。

3.2问题二:操作文件句柄时需要使用 Unicode 字符串操作

不能使用原始的 bytes 。

向文件写入二进制数据会报错:

?
1
2
3
4
5
6
7
8
# 写入二进制数据
with open ( 'test.txt' , "w+" ) as f:
     f.write(b "\xf1\xf2" )
 
 
# 输出结果
     f.write(b "\xf1\xf2" )
TypeError: write() argument must be str , not bytes
  • 报错是因为 w 模式必须以 文本 模式写入
  • 将模式改成 wb 即可正常写入二进制数据
?
1
2
3
4
5
6
7
8
9
10
11
with open ( 'test.txt' , "wb" ) as f:
     f.write(b "\xf1\xf2" )
读取文件中二进制数据
with open ( 'test.txt' , "r+" ) as f:
     f.read()
 
 
# 输出结果
     (result, consumed) = self ._buffer_decode(data, self .errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0 : invalid continuation byte
  • 报错是因为 r 模式必须以 文本 模式读取
  • 以文本模式操纵文件句柄时,系统会采用 默认的文本编码 方案处理二进制数据
  • 所以,上面那种写法会让系统通过 bytes.decode 把这份数据解码成 str 字符串,再用 str.encode 把字符串编码成二进制值
  • 然而对于大多数系统来说,默认的文本编码方案是UTF-8,所以系统很可能会把 b'\xf1\xf2\xf3\xf4\xf5' 当成  UTF-8 格式的字符串去解码,于是就会出现上面那样的错误

将模式改成 rb 即可正常读取二进制数据:

?
1
2
3
4
5
6
with open ( 'test.txt' , "rb" ) as f:
     print (b "\xf1\xf2" = = f.read())
 
 
# 输出结果
True

另一种改法,设置 encoding 参数指定字符串编码:

?
1
2
3
4
5
6
with open ( 'test.txt' , "r" , encoding = "cp1252" ) as f:
     print (f.read())
 
 
# 输出结果
ñò

这样也不会有异常了 。

需要注意:当前操作系统默认的字符集编码,Python 一行代码查看当前操作系统默认的编码标准 。

在 cmd 中执行

?
1
2
> python3 -c 'import locale; print(locale.getpreferredencoding())'
UTF-8

到此这篇关于Effective Python bytes 与 str 的区别的文章就介绍到这了,更多相关Python bytes 与 str 的区别内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。

原文链接:https://www.cnblogs.com/poloyy/p/15549664.html 。

最后此篇关于Effective Python bytes 与 str 的区别的文章就讲到这里了,如果你想了解更多关于Effective Python bytes 与 str 的区别的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com