我正在使用一个返回字节字符串的库,我需要将其转换为字符串。
虽然我不确定区别是什么 - 如果有的话。
计算机可以存储的唯一内容是字节。
要在计算机中存储任何内容,必须先对其进行编码,即将其转换为字节。例如:
-
如果要存储音乐,必须先使用MP3,WAV等对其进行编码。
-
如果要存储图片,必须先使用PNG,JPEG等对其进行编码。
-
如果要存储文本,必须先使用ASCII,UTF-8等对其进行编码。
MP3,WAV,PNG,JPEG,ASCII和UTF-8是编码的示例。编码是以字节表示音频,图像,文本等的格式。
在Python中,字节字符串就是:字节序列。它不是人类可读的。在引擎盖下,一切都必须转换为字节串,然后才能存储在计算机中。
另一方面,字符串(通常称为"字符串")是字符序列。它是人类可读的。字符串不能直接存储在计算机中,必须先对其进行编码(转换为字节串)。有多种编码可以将字符串转换为字节串,例如ASCII和UTF-8。
1
| 'I am a string'.encode('ASCII') |
上面的Python代码将使用编码ASCII对字符串'I am a string'进行编码。上面代码的结果将是一个字节字符串。如果你打印它,Python将它表示为b'I am a string'。但请记住,字节字符串不是人类可读的,只是Python在打印时从ASCII解码它们。在Python中,字节字符串由b表示,后跟字节字符串的ASCII表示。
如果您知道用于对其进行编码的编码,则可以将字节字符串解码回字符串。
1
| b'I am a string'.decode('ASCII') |
上面的代码将返回原始字符串'I am a string'。
编码和解码是逆操作。在将所有内容写入磁盘之前必须对其进行编码,并且必须先对其进行解码才能将其读取。
-
Zenadix值得一些荣誉。经过几年在这种环境中运作,他是第一个与我点击的解释。我可以在我的另一只手臂上纹身(一只手臂已经拥有"绝对最低限度,每个软件开发人员绝对必须知道关于Unicode和字符集(没有借口!)"作者Joel Spolsky"
-
绝对精彩。清醒易懂。但是,我想提一下这句话 -"如果你打印它,Python将它表示为b'我是一个字符串'"对于Python3来说是正确的,因为Python2字节和str是相同的。
-
我正在授予你这个赏金,因为它提供了一个非常人性化的解释,可以清楚地说明这个主题!
-
很好的答案。唯一可能添加的是更清楚地指出,历史上,程序员和编程语言倾向于明确或隐含地假设字节序列和ASCII字符串是相同的。 Python 3决定明确地打破这个假设,正确恕我直言。
-
恕我直言,Python3应该选择将字节作为hexa值打印为默认行为,并使用一些简单的函数转换为ascii或在ascii中打印。
-
链接到@ neil.millikin上面提到的Joel的帖子:joelonsoftware.com/2003/10/08/…
-
我真的很喜欢这个解释。但是,我认为它没有正确解释python(2.7)中的一些行为。例如,使用os.urandom(32)创建一个字符串(返回字节的repr)。要"解码"(使用此帖子中的含义)到base64字符串,实际上是encode('base64')。这很奇怪,与这篇文章所描述的内容背道而驰。
-
精湛的解释,在此之前我有一些困惑,但现在很清楚。谢谢zenadix
-
给这个男人一个饼干!没有不尊重,非常感谢您的详细解释。
假设Python 3(在Python 2中,这种差异有点不太明确) - 字符串是一系列字符,即unicode代码点;这些都是抽象的概念,不能直接存储在磁盘上。字节字符串是一系列不出所料的字节 - 可以存储在磁盘上的东西。它们之间的映射是一种编码 - 有很多这些(并且可能无限多) - 你需要知道哪种情况适用于特定情况才能进行转换,因为不同的编码可能映射相同的字节到另一个字符串:
1 2 3 4
| >>> 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()方法采用相反的方式:
1 2
| >>> 'τoρνo?'.encode('utf-8')
b'\xcf\x84o\xcf\x81\xce\xbdo\xcf\x82' |
-
为了澄清Python 2用户:str类型与bytes类型相同;这个答案等效地将unicode类型(在Python 3中不存在)与str类型进行比较。
-
从技术上讲,unicode不是默认编码,而utf-8编码是在内存中存储unicode字符串的默认字符编码。
-
@KshitijSaraogi也不是那么真实;整个句子都被编辑了,有点不幸。 Python 3 str对象的内存中表示不能从Python端访问或相关;数据结构只是一系列代码点。在PEP 393下,确切的内部编码是Latin-1,UCS2或UCS4之一,并且在首次请求后可以缓存utf-8表示,但是甚至不鼓励C代码依赖这些内部细节。
-
如果它们不能直接存储在磁盘上,那么它们如何存储在内存中?
-
@ore??ty他们确实必须以某种方式在内部进行编码,正是出于这个原因,但这并不是来自Python代码的暴露,就像你不必关心如何存储浮点数一样。
-
在这种情况下,默认编码是什么,即从文件中读取字符串时使用的编码?
在Python 2中,str由8位值的序列组成,而unicode由Unicode字符序列组成。 要记住的一件事是,如果str只包含7位ASCI字符,str和unicode可以与运算符一起使用。
在Python 3中,bytes由8位值的序列组成,而str由Unicode字符序列组成。 bytes和str不能与>或+等运算符一起使用。
使用辅助函数在Python 2中的str和unicode之间以及Python 3中的bytes和str之间进行转换可能很有用。
-
您可以查看此问题及其答案,以了解如何在Python 3中转换bytes和str。
从什么是Unicode:
Fundamentally, computers just deal with numbers. They store letters and other characters by assigning a number for each one.
......
Unicode provides a unique number for every character, no matter what the platform, no matter what the program, no matter what the language.
因此,当计算机表示字符串时,它会通过其唯一的Unicode编号查找存储在字符串计算机中的字符,这些数字存储在内存中。但是你无法直接将字符串写入磁盘或通过其唯一的Unicode编号在网络上传输字符串,因为这些数字只是简单的十进制数字。您应该将字符串编码为字节字符串,例如UTF-8。 UTF-8是一种能够编码所有可能字符的字符编码,它将字符存储为字节(看起来像这样)。因此编码的字符串可以在任何地方使用,因为UTF-8几乎在任何地方都受支持。当您从其他系统打开以UTF-8编码的文本文件时,您的计算机将对其进行解码并通过其唯一的Unicode编号在其中显示字符。当浏览器从网络接收编码UTF-8的字符串数据时,它会将数据解码为字符串(假设浏览器采用UTF-8编码)并显示字符串。
在python3中,您可以将字符串和字节字符串相互转换:
1 2 3 4
| >>> print('中文'.encode('utf-8'))
b'\xe4\xb8\xad\xe6\x96\x87'
>>> print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))
中文 |
总之,字符串用于显示给人类在计算机上读取,字节串用于存储到磁盘和数据传输。