在python3中是否均等存储在内存中?

问题描述 投票:0回答:2

众所周知,Python3 将所有字符串字符作为 Unicode 代码点。

type('\x0d')
<class 'str'>
type(b'\x0d')
<class 'bytes'>

b'\x0d'
的ascii为
13
,以
0000 0111
的形式存储在内存中,
'\x0d'
是否以与
0000 0111
相同的格式存储?它们在内存中是否相等?
挖掘更多让我更困惑:

#My python version
python3 --version
Python 3.9.2
#in python cli
len(b'\x0d')
1
import sys
print(sys.getsizeof(b'\x0d'))
34

b\x0d
在内存中不是以
00000111
的形式存储的吗?

print(sys.getsizeof('\x0d'))
50

使用

sys.getsizeof
让我明白:

  1. string
    bytes
    在python3中以不同的对象存储。
  2. 当我们说
    b\x0d
    在内存中以
    00000111
    的形式存储时,它是基于某种抽象层次,实际上
    b\x0d
    对于cython3在pc的内存中是以34字节存储的?
python-3.x unicode cpython
2个回答
1
投票

有兴趣的可以看看CPython中各个对象的内存内容。对象的大小可以通过

sys.getsizeof(obj)
查询,内存地址恰好是当前实现中对象的
id(obj)
ctypes
模块有一个
string_at
函数,它需要一个内存地址和大小来读取内存:

>>> import sys
>>> import ctypes
>>> x = '\x0d'
>>> ctypes.string_at(id(x), sys.getsizeof(x)).hex()
'02ca9a3b0000000070a427b3fb7f00000100000000000000c879dc5ef7a24b87e40000000000000000000000000000000d00'
>>> x = b'\x0d'
>>> ctypes.string_at(id(x), sys.getsizeof(x)).hex()
'01ca9a3b00000000b0b126b3fb7f00000100000000000000c879dc5ef7a24b870d00'

在上面你可以看到对象有不同的内存映像,但在这种情况下,至少,对象中的数据存储在最后一个字节

0d 00
并且由于 CPython 使用
latin-1
8 位编码而完全相同存储 Unicode 字符串(详见PEP 393)。 CPython 添加了一个空终止符作为另一个实现细节。其他字节表示 CPython 中
PyBytes
PyUnicode
对象实现中的数据。


0
投票

CPython 目前使用每个字符最少 8、16、32 位(在 LATIN-1、UTF-16(?)、UTF-32 中)对(文本)字符串进行编码,以适应字符串中包含的所有字符。

所以,如果你所有的字符都符合 LATIN-1 编码——它与 unicode 代码点 1:1 匹配 <256, it will use only one byte per character internally.

我似乎在某个地方(抱歉,这是一个问题的评论辩论,但我现在找不到)有未来计划将文本字符串 utf-8 编码保存在内存中,以避免大量绝大多数与文本相关的工作流中的开销,其中 utf-8 字节字符串被解码为很少使用的内部表示。 Pypy 目前使用这种方法。

© www.soinside.com 2019 - 2024. All rights reserved.