gpt4 book ai didi

Python - 关于 Python 中字符串如何存储和处理的混淆

转载 作者:行者123 更新时间:2023-12-01 01:06:22 25 4
gpt4 key购买 nike

我正在尝试了解字符串在 Python 中的工作原理,但在破译各种功能方面遇到了困难。这是我的理解。希望得到关于如何记住这些细微差别的更正和新观点。

  • 首先,我知道 Unicode 的发展是为了适应世界各地的多种语言和口音。但是python是如何存储字符串的呢?如果我定义 s = 'hello'字符串 s 的编码是什么被储存了?是统一码吗?或者它以普通字节存储?关于做type(s)我得到的答案是 <type 'str'> 。然而,当我这样做时us = unicode(s) , us属于 <type 'unicode'> 类型。是us一个str输入或者实际上是否有 unicode输入Python?

  • 此外,我知道为了存储空间,我知道我们使用 encode() 将字符串编码为字节。功能。所以假设bs = s.encode('utf-8', errors='ignore')将返回一个字节对象。所以,现在当我写bs时到一个文件,我应该打开 wb 中的文件吗?模式?我看到如果在 w 打开模式,它将文件中的字符串存储为 b"<content in s>"

  • decode() 函数是做什么的?(我知道,这个问题太开放了。)是不是,我们将其应用于 bytes 对象,并将字符串转换为我们选择的编码?或者它总是将其转换回 Unicode 序列?从以下几行中可以得出任何其他见解吗?

>>> s = 'hello'
>>> bobj = bytes(s, 'utf-8')
>>> bobj
'hello'
>>> type(bobj)
<type 'str'>
>>> bobj.decode('ascii')
u'hello'
>>> us = bobj.decode('ascii')
>>> type(us)
<type 'str'>
  • str(object) 怎么样?工作?我读到它将尝试执行对象描述中的 str() 函数。但是这个函数对 Unicode 字符串和常规字节编码字符串的作用有何不同?

提前致谢。

最佳答案

重要:下面描述了 python3 行为。虽然 python2 在概念上有一些相似之处,但公开的行为会有所不同。

简而言之:由于python3中支持unicode,字符串对象是更高级别的抽象。如何在内存中表示它取决于解释器。因此,当涉及到序列化(例如,将字符串的文本表示形式写入文件)时,需要首先使用指定的编码(例如 UTF-8)将其显式编码为字节序列。字节到字符串的转换(即解码)也是​​如此。在 python2 中,使用 unicode 类可以实现相同的行为,而 strbytes 的同义词。

虽然这不是您问题的直接答案,但请看一下这些示例:

import sys

e = ''
print(len(e)) # 0
print(sys.getsizeof(e)) # 49

a = 'hello'
print(len(a)) # 5
print(sys.getsizeof(a)) # 54

u = 'hello平仮名'
print(len(u)) # 8
print(sys.getsizeof(u)) # 90
print(len(u[1:])) # 7
print(sys.getsizeof(u[1:])) # 88
print(len(u[:-1])) # 7
print(sys.getsizeof(u[:-1])) # 88
print(len(u[:-2])) # 6
print(sys.getsizeof(u[:-2])) # 86
print(len(u[:-3])) # 5
print(sys.getsizeof(u[:-3])) # 54
print(len(u[:-4])) # 4
print(sys.getsizeof(u[:-4])) # 53

j = 'hello😋😋😋'
print(len(j)) # 8
print(sys.getsizeof(j)) # 108
print(len(j[:-1])) # 7
print(sys.getsizeof(j[:-1])) # 104
print(len(j[:-2])) # 6
print(sys.getsizeof(j[:-2])) # 100

字符串在 Python 中是不可变的,这使解释器能够在创建阶段决定字符串的编码方式。让我们回顾一下上面的数字:

  • 空字符串对象的开销为 49 个字节。
  • 长度为 5 的 ASCII 符号的字符串的大小为 49 + 5。编码每个符号使用 1 个字节。
  • 即使具有混合(ASCII + 非 ASCII)符号的字符串也具有更高的内存占用量虽然长度仍然是8。
  • uu[1:] 的区别以及 uu[: -1]90 - 88 = 2 字节。 IE。每个符号使用 2 个字节进行编码。即使字符串的前缀可以用每个符号 1 个字节进行编码。这为我们提供了对字符串进行恒定时间索引操作的巨大优势,但我们付出了额外的内存开销。
  • 字符串j的内存占用甚至更高。只是因为我们无法使用每个符号 2 个字节对其中的所有符号进行编码,因此解释器现在每个符号使用 4 个字节。

好的,继续检查行为。我们已经知道,解释器以每个符号偶数个字节的方式存储字符串,以便我们通过索引进行 O(1) 访问。然而,我们也知道 UTF-8 使用符号的可变长度表示。让我们来证明一下:

j = 'hello😋😋😋'
b = j.encode('utf8') # b'hello\xf0\x9f\x98\x8b\xf0\x9f\x98\x8b\xf0\x9f\x98\x8b'
print(len(b)) # 17

因此,我们可以看到,前 5 个字符使用每个符号 1 个字节进行编码,而其余 3 个符号使用每个符号 (17 - 5)/3 = 4 字节进行编码。这也解释了为什么 python 在底层使用每个符号 4 个字节的表示形式。

另一种方式是,当我们有一个字节序列并将其解码为字符串时,解释器将决定内部字符串表示形式(每个符号 1、2 或 4 个字节)并它对程序员来说是完全不透明的。唯一必须透明的是字节序列的编码。我们必须告诉解释器如何处理字节。而我们应该让他决定字符串对象的内部表示。

关于Python - 关于 Python 中字符串如何存储和处理的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55312480/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com