字符串对象如何存储在内存中?为什么要在python中将字符串对象转换为字节对象?

时间:2020-07-06 16:54:20

标签: python string object byte

x=bytes("Hello! Welcome to Python")

在上面的代码行中,一个字符串对象正在转换为字节对象。但是,即使不将其转换为字节对象,通过遵循某种编码(ASCII或unicode)将其作为字符串对象最终存储在内存中(以二进制形式)有什么用呢?

1 个答案:

答案 0 :(得分:0)

使用空字符串或一个字符的ASCII字符串时,Python使用字符串插入。实习字符串充当单例,也就是说,如果有两个相同的实习字符串,则内存中只有一个副本。

>>> a = 'hello'
>>> b = 'world'
>>> a[4],b[1]
('o', 'o')
>>> id(a[4]), id(b[1]), a[4] is b[1]
(4567926352, 4567926352, True)
>>> id('')
4545673904
>>> id('')
4545673904

如您所见,两个字符串切片都指向内存中的相同地址。这是有可能的,因为Python字符串是不可变的。

在Python中,字符串实习不会限制为字符或空字符串。如果在代码编译期间创建的字符串的长度不超过20个字符,则也可以对其进行屏蔽。

这包括:

  1. 函数和类名
  2. 变量名
  3. 参数名称
  4. 常量(代码中定义的所有字符串)
  5. 字典键
  6. 属性名称

在Python REPL中按Enter键时,您的语句将被编译为字节码。这就是为什么REPL中的所有短字符串也会被扣留的原因。

>>> a = 'teststring'
>>> b = 'teststring'
>>> id(a), id(b), a is b
(4569487216, 4569487216, True)
>>> a = 'test'*5
>>> b = 'test'*5
>>> len(a), id(a), id(b), a is b
(20, 4569499232, 4569499232, True)
>>> a = 'test'*6
>>> b = 'test'*6
>>> len(a), id(a), id(b), a is b
(24, 4569479328, 4569479168, False)

此示例将不起作用,因为此类字符串不是常量:

>>> open('test.txt','w').write('hello')
5
>>> open('test.txt','r').read()
'hello'
>>> a = open('test.txt','r').read()
>>> b = open('test.txt','r').read()
>>> id(a), id(b), a is b
(4384934576, 4384934688, False)
>>> len(a), id(a), id(b), a is b
(5, 4384934576, 4384934688, False)

字符串嵌入技术可节省成千上万个重复的字符串分配。在内部,字符串实习由全局字典维护,该字典将字符串用作键。要检查内存中是否已经存在相同的字符串,Python会执行字典成员资格操作。

unicode对象几乎是16000行C代码,因此有许多小的优化未在本文中提及。如果您想了解有关Python中Unicode的更多信息,建议您阅读有关字符串的PEP并检查unicode对象的代码。

相互转换通常很普遍,但是由于在处理文件或机器学习(Pickle File)时,我们广泛要求将字符串转换为字节,因此如今在字符串至字节之间的转换更为普遍。让我们讨论执行此操作的某些方法。

字节对象是字节序列。这些字节对象是机器可读的,可以直接存储在磁盘上。另一方面,字符串是人类可读的形式,需要进行编码,以便可以将它们存储在磁盘上