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

时间:2011-06-03 07:06:54

标签: python string character byte

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

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

8 个答案:

答案 0 :(得分:287)

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

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

  • 如果您要存储音乐,则必须先使用MP3WAV编码
  • 如果您要存储图片,则必须先使用PNGJPEG编码图片。
  • 如果您要存储文字,则必须先使用ASCIIUTF-8编码

MP3WAVPNGJPEGASCIIUTF-8编码的示例。编码是一种以字节为单位表示音频,图像,文本等的格式。

在Python中,字节字符串就是:字节序列。它不是人类可读的。在引擎盖下,必须先将所有内容转换为字节字符串,然后才能将其存储在计算机中。

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

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

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

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

ASCII

上面的代码将返回原始字符串b'I am a string'.decode('ASCII')

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

答案 1 :(得分:189)

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

>>> 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ς'

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

>>> 'τoρνoς'.encode('utf-8')
b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82'

答案 2 :(得分:10)

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

在Python 3 中,bytes由8位值序列组成,而str由Unicode字符序列组成。 bytesstr不能与>+等运营商一起使用。

使用辅助函数在Python 2中的strunicode之间以及Python 3中的bytesstr之间进行转换可能很有用。

答案 3 :(得分:3)

来自What is Unicode

  

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

     

...

     

Unicode为每个角色提供唯一的编号,无论平台是什么,无论程序是什么,无论语言是什么。

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

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

>>> print('中文'.encode('utf-8'))
b'\xe4\xb8\xad\xe6\x96\x87'
>>> print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))
中文 

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

答案 4 :(得分:3)

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

>>> 'š'.encode('utf-8')
b'\xc5\xa1'

在此示例中,让我们以二进制形式显示字节序列:

>>> bin(int(b'\xc5\xa1'.hex(), 16))
'0b1100010110100001'

现在,通常无法将信息解码回来,而不知道它是如何编码的。仅在知道使用utf-8文本编码的情况下,您才能遵循algorithm for decoding utf-8并获取原始字符串:

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

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

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

答案 5 :(得分:1)

Unicode是一种公认​​的格式,用于字符的二进制表示和各种格式(例如,小写/大写,换行,回车)和其他“事物”(例如,表情符号)。无论是在内存中还是在文件中,计算机都能够存储unicode表示(一系列位),而不是存储ascii表示(一系列不同的位)或任何其他表示形式(一系列的位) )。

要进行通信,通信各方必须就将使用哪种表示形式达成共识。

因为unicode试图表示 all 在人与计算机之间的通信中可能使用的字符(以及其他“事物”),所以它需要大量的位来表示许多字符(或事物),而不是其他试图代表有限的字符/事物的表示系统。为了“简化”并可能适应历史使用,Unicode代码表示几乎专门转换为其他表示形式(例如ascii),以将字符存储在文件中。

不是 不能用于在文件中存储字符或通过 any 通信通道传输字符的情况,只是不是。

术语“字符串”没有精确定义。通常,“字符串”是指一组字符/事物。在计算机中,这些字符可以以多种不同的逐位表示形式中的任何一种形式存储。 “字节字符串”是一组字符的存储,这些字符使用八位(八位称为字节)的表示形式存储。由于这些天来,计算机使用unicode系统(由可变字节数表示的字符)将字符存储在内存中,并使用字节字符串(由单字节表示的字符)将字符存储到文件中,因此在表示字符之前必须先进行转换内存中的内容将被移入文件中的存储空间。

答案 6 :(得分:0)

Python语言包括strbytes作为标准的“内置类型”。换句话说,它们都是类。我认为尝试合理化为什么以这种方式实现Python并不值得。

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

casefold
encode
format
format_map
isdecimal
isidentifier
isnumeric
isprintable

以下方法对于bytes类是唯一的:

decode
fromhex
hex

答案 7 :(得分:0)

简单来说,想想我们的自然语言,如英语、孟加拉语、汉语等。在说话时,所有这些语言都会发声。但是,即使我们在这里,我们是否理解所有这些? - 答案通常是否定的。所以,如果我说我懂英语,​​这意味着我知道这些声音是如何编码成一些有意义的英语单词的,我只是以同样的方式解码这些声音来理解它们。因此,对于任何其他语言也是如此,如果您知道它,您就会想到该语言的编码器-解码器包,同样,如果您不知道它,您就是没有这个。

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