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

She*_*don 168 python string byte character

我正在使用一个返回字节字符串的库,我需要将其转换为字符串.

虽然我不确定区别是什么 - 如果有的话.

Zen*_*dix 330

计算机可以存储的唯一内容是字节.

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

  • 如果你想存储的音乐,你必须先进行编码使用它MP3,WAV等等.
  • 如果你想存储图片,必须先进行编码使用它PNG,JPEG等等.
  • 如果你想存储文本,必须先进行编码使用它ASCII,UTF-8等等.

MP3,WAV,PNG,JPEG,ASCIIUTF-8是的示例编码.编码是以字节表示音频,图像,文本等的格式.

在Python中,字节字符串就是:字节序列.它不是人类可读的.在引擎盖下,一切都必须转换为字节串,然后才能存储在计算机中.

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

'I am a string'.encode('ASCII')
Run Code Online (Sandbox Code Playgroud)

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

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

b'I am a string'.decode('ASCII')
Run Code Online (Sandbox Code Playgroud)

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

编码和解码是逆操作.在将所有内容写入磁盘之前必须对其进行编码,并且必须先对其进行解码才能将其读取.

  • Zenadix值得一些荣誉.经过几年在这种环境中运作,他是第一个与我点击的解释.我可以在我的另一只手臂上纹身(一只手臂已经拥有"绝对最低限度,每个软件开发人员绝对必须知道关于Unicode和字符集(没有借口!)"作者Joel Spolsky" (50认同)
  • 绝对精彩.清醒易懂.但是,我想提一下这句话 - "如果你打印它,Python将它表示为b'我是一个字符串'"对于Python3来说是正确的,因为Python2字节和str是相同的. (4认同)
  • 链接到由@ neil.millikin上述乔尔的帖子:https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about- Unicode的和字符集,没有借口/ (4认同)
  • 我正在授予你这个赏金,因为它提供了一个非常人性化的解释,可以清楚地说明这个主题! (3认同)
  • 好答案。唯一可以添加的是要更清楚地指出,从历史上看,程序员和编程语言倾向于显式或隐式地*假定字节序列和ASCII字符串是同一件事*。Python 3决定明确地打破这一假设,正确的恕我直言。 (3认同)
  • 恕我直言,Python3 应该选择将字节打印为十六进制值作为默认行为,并使用一些简单的函数转换为 ascii 或以 ascii 打印。 (2认同)

lvc*_*lvc 221

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

>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-16')
'?????'
>>> b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'.decode('utf-8')
'?o??o?'
Run Code Online (Sandbox Code Playgroud)

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

>>> '?o??o?'.encode('utf-8')
b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'
Run Code Online (Sandbox Code Playgroud)

  • 为了澄清Python 2用户:`str`类型与`bytes`类型相同; 这个答案等效地将`unicode`类型(在Python 3中不存在)与`str`类型进行比较. (7认同)
  • 如果它们不能直接存储在磁盘上,那么它们如何存储在内存中? (3认同)
  • @KshitijSaraogi也不是那么真实; 整个句子都被编辑了,有点不幸.Python 3`str`对象的内存中表示不能从Python端访问或相关; 数据结构只是一系列代码点.在[PEP 393](https://www.python.org/dev/peps/pep-0393/)下,确切的内部编码是Latin-1,UCS2或UCS4之一,并且可以缓存utf-8表示在首次请求之后,甚至不鼓励C代码依赖这些内部细节. (2认同)
  • @ore​​ty 正是出于这个原因,它们确实必须在内部以*某种方式* 进行编码,但这并不是 Python 代码中的 expos3s,就像您不必关心浮点数的存储方式一样。 (2认同)
  • @ChrisStryczynski 看到上面的评论 - 确保它们*以某种方式*存储在内存中,但该形式被显式抽象掉。事实上,如今,它可以在程序的生命周期内发生变化,并且在不同的字符串之间有所不同,甚至可能不止一个(某些编码被缓存),具体取决于其中的字符 - 但这是您唯一需要担心的情​​况也就是说,如果您正在破解字符串类型本身的实现。 (2认同)

lmi*_*asf 12

在Python 2中,str由8位值unicode序列组成,同时由Unicode字符序列组成.需要记住的一点是,如果只包含7位ASCI字符str,unicode则可以与运算符一起使用str.

在Python 3中,bytes由8位值str序列组成,同时由Unicode字符序列组成.bytes并且str不能与像>或等的运营商一起使用+.

这可能是使用辅助功能之间进行转换有用的strunicode在Python 2之间,以及bytesstr在Python 3.


Jey*_*mon 8

让我们有一个简单的单字符字符串\'\xc5\xa1\'并将其编码为字节序列:

\n
>>> \'\xc5\xa1\'.encode(\'utf-8\')\nb\'\\xc5\\xa1\'\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
>>> bin(int(b\'\\xc5\\xa1\'.hex(), 16))\n\'0b1100010110100001\'\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
>>> \'\xc5\xa1\'.encode(\'utf-8\')\nb\'\\xc5\\xa1\'\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
>>> chr(int(\'101100001\', 2))\n\'\xc5\xa1\'\n
Run Code Online (Sandbox Code Playgroud)\n


Sam*_*ang 6

来自什么是 Unicode?

\n
\n

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

\n

......

\n

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

\n
\n

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

\n

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

\n

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

\n
>>> print(\'\xe4\xb8\xad\xe6\x96\x87\'.encode(\'utf-8\'))\nb\'\\xe4\\xb8\\xad\\xe6\\x96\\x87\'\n>>> print(b\'\\xe4\\xb8\\xad\\xe6\\x96\\x87\'.decode(\'utf-8\'))\n\xe4\xb8\xad\xe6\x96\x87\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

  • “*Unicode 为每个字符提供唯一的编号*”:1/ Unicode(来自 Unicode 联盟)不是一种编码,而是一个字形名称列表,UTF-8 或 UTF-32(来自 ISO)是 UTF 中的“T”是为了‘转变’。2/ 您可能指的是 UTF-8,但数字并不唯一。[维基百科](https://en.wikipedia.org/wiki/Unicode):“UTF-8,占主导地位的编码 [...] 使用一个字节表示前 128 个代码点,最多使用 4 个字节表示其他字符”。要使所有代码点都有唯一的序列,则需要使用 UTF-32,它为每个代码点分配 4 个字节,但实际中并未使用这种编码。 (2认同)