python如何在内存中存储对象

时间:2018-10-07 20:55:02

标签: python object

据我了解,列表是一块连续的内存位置,其中包含指向内存中元素值的指针。如下所示:

list in memory

我的问题是它与内存中的对象是否相同,即: 假设我有一个带有以下实现的init方法的点类:

class Point: 
    def __init__(self, x, y): 
        self.x = x
        self.y = y

然后我创建一个新的点对象:

p = Point(4,6)

指向p.x的指针和指向p.y的指针在内存中会相邻吗?

2 个答案:

答案 0 :(得分:5)

Python(即编程语言)没有内存位置或指针的概念。因此,从这个角度来看,您的问题没有答案。您的问题只能针对python的特定实现来回答,例如CPython

也就是说,对于几乎所有的python实现,答案都是。这是因为(大多数)python类将其属性存储在字典中。我们可以通过名称__dict__访问该词典:

>>> Point(1, 2).__dict__
{'x': 1, 'y': 2}

由于字典必须高效并且具有O(1)查找时间,因此通常将其实现为hash tables。在哈希表中xy彼此相邻的可能性很小。

但是,并非所有类都使用字典来存储属性。有两个例外:

  • 内置类,例如字典,整数,字符串等。
  • 具有__slots__属性的类

特殊的__slots__类变量允许我们告诉python该类将具有哪些属性。然后,Python将仅分配足够的内存来存储这些属性,而尝试创建任何其他属性将导致错误:

class Point: 
    __slots__ = ('x', 'y')

    def __init__(self, x, y): 
        self.x = x
        self.y = y
>>> p = Point(1, 2)
>>> p.x
1
>>> p.__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Point' object has no attribute '__dict__'
>>> p.z = 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Point' object has no attribute 'z'

如果一个类使用__slots__,则其所有属性很可能彼此相邻地存储在内存中。但这仍然不能保证。 python实现可以根据需要存储属性。

答案 1 :(得分:1)

通常不会这样,因为普通对象的属性存储在哈希表中,并以属性名称作为关键字。其他实现也是可能的(例如Self和某些Javascript实现),但是据我所知,目前还没有Python实现。

如果使用元组(如collections.namedtuple中的那样(实现非常有启发性),则指针将是相邻的。