字符串和字节字符串有什么区别?

2024-12-19 09:23:00
admin
原创
83
摘要:问题描述:我正在使用一个返回“字节字符串”的库(bytes),我需要将其转换为字符串。这两者之间真的有区别吗?它们之间有什么关系?我该如何进行转换?解决方案 1:计算机唯一可以存储的东西是字节。要在计算机中存储任何东西,必须先对其进行编码,即将其转换为字节。例如:如果您想存储音乐,您必须首先使用MP3、WAV...

问题描述:

我正在使用一个返回“字节字符串”的库(bytes),我需要将其转换为字符串。

这两者之间真的有区别吗?它们之间有什么关系?我该如何进行转换?


解决方案 1:

计算机唯一可以存储的东西是字节。

要在计算机中存储任何东西,必须先对其进行编码,即将其转换为字节。例如:

  • 如果您想存储音乐,您必须首先使用MP3、WAV等对其进行编码

  • 如果要存储图片,必须首先使用PNG、JPEG等对其进行编码。

  • 如果要存储文本,必须首先使用ASCII、UTF-8等对其进行编码

MP3、WAV、PNG、JPEG、ASCII 和 UTF-8 是编码的示例。编码是一种以字节为单位表示音频、图像、文本等的格式。

在 Python 中,字节字符串就是字节序列。它不是人类可读的。在底层,所有内容都必须转换为字节字符串,然后才能存储在计算机中。

另一方面,字符串(通常简称为“字符串”)是字符序列。它是人类可读的。字符串不能直接存储在计算机中,必须先进行编码(转换为字节字符串)。有多种编码可以将字符串转换为字节字符串,例如 ASCII 和 UTF-8。

'I am a string'.encode('ASCII')

上述 Python 代码将使用编码 ASCII 对字符串“I am a string”b'I am a string'进行编码。上述代码的结果将是一个字节字符串。如果打印它,Python 会将其表示为。但请记住,字节字符串不是人类可读的,只是 Python 在打印它们时将它们从 ASCII 解码。在 Python 中,字节字符串由表示b,后跟字节字符串的 ASCII 表示。

如果您知道用于对字节字符串进行编码的编码,则可以将其解码回字符串。

b'I am a string'.decode('ASCII')

上述代码将返回原始字符串'I am a string'

编码和解码是逆操作。所有内容在写入磁盘之前都必须进行编码,并且必须进行解码才能供人读取。

解决方案 2:

假设 Python 3(在 Python 2 中,这种差异定义得不太明确) - 字符串是字符序列,即unicode 代码点;这些是抽象概念,不能直接存储在磁盘上。字节字符串是一系列字节,这并不奇怪 -可以存储在磁盘上的东西。它们之间的映射是一种编码- 有很多这样的编码(并且可能有无限多的编码) - 您需要知道在特定情况下适用哪种编码才能进行转换,因为不同的编码可能会将相同的字节映射到不同的字符串:

>>> b'xcfx84oxcfx81xcexbdoxcfx82'.decode('utf-16')
'蓏콯캁澽苏'
>>> b'xcfx84oxcfx81xcexbdoxcfx82'.decode('utf-8')
'τoρνoς'

一旦知道要使用哪一个,就可以使用.decode()字节字符串的方法从中获取正确的字符串,如上所述。为了完整起见,.encode()字符串的方法与之相反:

>>> 'τoρνoς'.encode('utf-8')
b'xcfx84oxcfx81xcexbdoxcfx82'

解决方案 3:

注意:由于 Python 2 的生命周期结束已经非常接近,我将更详细地阐述我对 Python 3 的答案。

在 Python 3 中

bytes由 8 位无符号值序列组成,而str由表示人类语言文本字符的 Unicode 代码点序列组成。

>>> # bytes
>>> b = b'hx65llo'
>>> type(b)
<class 'bytes'>
>>> list(b)
[104, 101, 108, 108, 111]
>>> print(b)
b'hello'
>>>
>>> # str
>>> s = 'nai/u0308ve'
>>> type(s)
<class 'str'>
>>> list(s)
['n', 'a', 'i', '̈', 'v', 'e']
>>> print(s)
naïve

尽管bytesstr似乎以相同的方式工作,但它们的实例彼此不兼容,即bytesstr实例不能与>和 等运算符一起使用+。此外,请记住,比较bytesstr实例是否相等,即使用==,即使它们包含完全相同的字符,也将始终评估为False

>>> # concatenation
>>> b'hi' + b'bye' # this is possible
b'hibye'
>>> 'hi' + 'bye' # this is also possible
'hibye'
>>> b'hi' + 'bye' # this will fail
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat str to bytes
>>> 'hi' + b'bye' # this will also fail
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "bytes") to str
>>>
>>> # comparison
>>> b'red' > b'blue' # this is possible
True
>>> 'red'> 'blue' # this is also possible
True
>>> b'red' > 'blue' # you can't compare bytes with str
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'bytes' and 'str'
>>> 'red' > b'blue' # you can't compare str with bytes
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'str' and 'bytes'
>>> b'blue' == 'red' # equality between str and bytes always evaluates to False
False
>>> b'blue' == 'blue' # equality between str and bytes always evaluates to False
False

处理使用内置函数返回的文件时,还存在bytes另一个问题。一方面,如果您想要从文件读取或写入二进制数据,请始终使用二进制模式(如“rb”或“wb”)打开文件。另一方面,如果您想要从文件读取或写入 Unicode 数据,请注意计算机的默认编码,因此如有必要,请传递参数以避免意外。str`open`encoding

在 Python 2 中

str由 8 位值序列组成,而unicode由 Unicode 字符序列组成。需要注意的是,如果仅由 7 位 ASCI 字符组成,strunicode可以与运算符一起使用。str

str使用辅助函数在 Python 2 中在和之间unicode以及在 Python 3 中在bytes和之间进行转换可能会很有用。str

解决方案 4:

让我们拿一个简单的单字符字符串'š'并将其编码为一个字节序列:

>>> 'š'.encode('utf-8')
b'xc5xa1'

为了本例的目的,我们以二进制形式显示字节序列:

>>> bin(int(b'xc5xa1'.hex(), 16))
'0b1100010110100001'

现在,如果不知道信息是如何编码的,通常无法将其解码回来。只有当您知道使用了 UTF-8 文本编码时,您才能按照解码 UTF-8 的算法并获取原始字符串:

11000101 10100001
   ^^^^^   ^^^^^^
   00101   100001

您可以将二进制数显示101100001回字符串:

>>> chr(int('101100001', 2))
'š'

解决方案 5:

来自什么是 Unicode?:

从根本上讲,计算机只处理数字。它们通过为每个字母和其他字符分配一个数字来存储它们。

......

Unicode 为每个字符提供了一个唯一的编号,无论什么平台,无论什么程序,无论什么语言。

因此,当计算机表示字符串时,它会通过字符的唯一 Unicode 编号查找存储在计算机中的字符,这些数字存储在内存中。但是您不能通过其唯一的 Unicode 编号直接将字符串写入磁盘或在网络上传输字符串,因为这些数字只是简单的十进制数。您应该将字符串编码为字节字符串,例如UTF-8。UTF-8 是一种能够对所有可能字符进行编码的字符编码,它将字符存储为字节(看起来像这样)。因此编码的字符串可以在任何地方使用,因为几乎所有地方都支持 UTF-8。当您从其他系统打开以 UTF-8 编码的文本文件时,您的计算机将对其进行解码并通过其唯一的 Unicode 编号显示其中的字符。

当浏览器从网络接收到UTF-8编码的字符串数据时,它会将数据解码为字符串(假设浏览器采用UTF-8编码)并显示该字符串。

在 Python 3 中,你可以将字符串和字节字符串相互转换:

>>> print('中文'.encode('utf-8'))
b'xe4xb8xadxe6x96x87'
>>> print(b'xe4xb8xadxe6x96x87'.decode('utf-8'))
中文

总之,字符串是为了在计算机上显示给人看的,而字节字符串是为了存储到磁盘和数据传输的。

解决方案 6:

Unicode 是字符和各种格式(例如,小写/大写、换行符和回车符)以及其他“事物”(例如,表情符号)的二进制表示的约定格式。计算机存储 Unicode 表示(一系列位)的能力(无论是在内存中还是在文件中)不亚于存储 ASCII表示(不同的一系列位)或任何其他表示(一系列位)。

为了进行沟通,沟通双方必须就使用何种表示方式达成一致。

由于 Unicode 力图表示人与人之间和计算机之间通信中使用的所有可能的字符(以及其他“事物”),因此与其他力图表示一组更有限的字符/事物的表示系统相比,它需要更多的位数来表示许多字符(或事物)。为了“简化”,也许是为了适应历史用法,Unicode 表示几乎完全转换为其他表示系统(例如 ASCII),以便在文件中存储字符。

这并不是说 Unicode不能用于在文件中存储字符,或通过任何通信渠道传输字符。只是事实并非如此

术语“字符串”没有精确的定义。“字符串”在其常见用法中是指一组字符/事物。在计算机中,这些字符可以以多种不同的逐位表示形式存储。“字节字符串”是使用八位(八位称为一个字节)表示存储的一组字符。由于如今计算机使用 Unicode 系统(由可变数量的字节表示的字符)将字符存储在内存中,并使用字节字符串(由单个字节表示的字符)将字符存储到文件中,因此在将内存中表示的字符移动到文件中之前必须进行转换。

解决方案 7:

字符串是一串串在一起的项目。字节字符串是字节序列,例如b'xcexb1xcexac'表示"αά"。字符串是一串字符,例如"αά"。与序列同义。

字节串可以直接存储到磁盘,而字符串(字符串)不能直接存储在磁盘上,他们之间的映射就是编码。

解决方案 8:

简单来说,想想我们的自然语言,如英语、孟加拉语、中文等。说话时,所有这些语言都会发出声音。但即使我们听到了,我们能理解它们吗?

答案通常是否定的。所以,如果我说我懂英语,​​那就意味着我知道这些声音是如何编码成一些有意义的英语单词的,我只需以同样的方式解码这些声音就可以理解它们。所以,其他语言也是如此。如果你懂,你脑子里就有这种语言的编码器-解码器包,如果你不懂,你就没有这个。

数字系统也是如此。就像我们自己一样,我们只能用耳朵听声音,用嘴发出声音,计算机只能存储字节和读取字节。因此,某些应用程序知道如何读取字节并解释它们(例如要考虑多少字节才能理解任何信息),并以相同的方式写入,以便其他应用程序也能理解它。但如果没有理解(编码器-解码器),写入磁盘的所有数据都只是字节串。

解决方案 9:

Python 语言将strbytes作为标准“内置类型”。换句话说,它们都是类。我认为没有必要试图解释 Python 为何以这种方式实现。

话虽如此,strbytes彼此非常相似。两者共享大部分相同的方法。以下方法是该类独有的str

casefold
encode
format
format_map
isdecimal
isidentifier
isnumeric
isprintable

以下方法是bytes该类所特有的:

decode
fromhex
hex
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   990  
  在项目管理领域,CDCP(Certified Data Center Professional)认证评审是一个至关重要的环节,它不仅验证了项目团队的专业能力,还直接关系到项目的成功与否。在这一评审过程中,沟通技巧的运用至关重要。有效的沟通不仅能够确保信息的准确传递,还能增强团队协作,提升评审效率。本文将深入探讨CDCP...
华为IPD流程   26  
  IPD(Integrated Product Development,集成产品开发)是一种以客户需求为核心、跨部门协同的产品开发模式,旨在通过高效的资源整合和流程优化,提升产品开发的成功率和市场竞争力。在IPD培训课程中,掌握关键成功因素是确保团队能够有效实施这一模式的核心。以下将从五个关键成功因素展开讨论,帮助企业和...
IPD项目流程图   27  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司在其全球化进程中逐步构建和完善的一套高效产品开发管理体系。这一流程不仅帮助华为在技术创新和产品交付上实现了质的飞跃,还为其在全球市场中赢得了显著的竞争优势。IPD的核心在于通过跨部门协作、阶段性评审和市场需求驱动,确保...
华为IPD   26  
  华为作为全球领先的通信技术解决方案提供商,其成功的背后离不开一套成熟的管理体系——集成产品开发(IPD)。IPD不仅是一种产品开发流程,更是一种系统化的管理思想,它通过跨职能团队的协作、阶段评审机制和市场需求驱动的开发模式,帮助华为在全球市场中脱颖而出。从最初的国内市场到如今的全球化布局,华为的IPD体系在多个领域展现...
IPD管理流程   53  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用