【问题标题】:How to be memory-efficient with variables in classes?如何使用类中的变量提高内存效率?
【发布时间】:2015-01-25 15:46:48
【问题描述】:

假设,例如,我有一个这样的类:

def class Foo(object):
    def __init__(self,x):
        self.x = x
    def lookup(self):
        return dict[x]

lookup 函数的目的是在字典中查找x 并返回值。假设这个字典非常大。我想知道是在类中声明dict,还是将dict声明为全局变量。

我担心内存效率:dict 将保持不变,我希望它不会占用过多的内存。因此,我在问类如何使用内存。如果我声明例如Foo 的 50,000 个实例,并且我在 Foo 中声明了字典,这是否意味着我正在生成 50,000 个 Foo 的副本?而如果我将 dict 称为全局变量,我不会产生任何额外的副本?

如何制作尽可能少的 dict 副本?理想情况下,这个程序只有一个。

【问题讨论】:

  • @Andreas 是的,内存中Foo 的两个实例是不同的——但是这些对象上的方法是否也不同?我不明白为什么每次都会复制相同的功能(lookup)。只维护一个指向 lookup 函数的指针是最有效的。

标签: python class memory memory-management dictionary


【解决方案1】:

在这种情况下,您应该将dict 作为全局变量。内部变量的想法是您可以独立更改和使用它们而不会发生冲突。这就是为什么Foo 的每个实例都有自己的dict 副本。 (实际上命名为 self.dict - 就像您应该在使用对象的内部变量的 lookup 函数中将 self.x 作为参数一样。)使用全局变量既可以节省内存,又可以防止您的 dict 中可能存在不同版本的可能性程序。

【讨论】:

    【解决方案2】:

    每个对象本质上都有一个字典,如果您希望提高内存效率,您可以使用一个对象来存储所有 50k 而不是 50k 对象。

    如果您有一个数据存储对象,它采用名称或索引作为get 的参数以及set 的值,您将只有一个字典来存储您的所有值。当然,如果您在 set 方法中使用 setattr(self, name, value),它将允许您以 obj.name 的形式访问这些值 - 唯一的事情是 python 已经为您做到了。

    In [4]: class DS(object):
       ...:     def __init__(self):
       ...:         pass
       ...:
    
    In [5]: ds = DS()
    
    In [6]: ds.a = 'A'
    
    In [7]: ds.b = 2
    
    In [8]: ds
    Out[8]: <__main__.DS at 0x3c82db0>
    
    In [9]: ds.a
    Out[9]: 'A'
    
    In [10]: ds.b
    Out[10]: 2
    
    In [11]: dir(ds)
    Out[11]:
    ['__class__',
     '__delattr__',
     '__dict__',
     '__doc__',
     '__format__',
     '__getattribute__',
     '__hash__',
     '__init__',
     '__module__',
     '__new__',
     '__reduce__',
     '__reduce_ex__',
     '__repr__',
     '__setattr__',
     '__sizeof__',
     '__str__',
     '__subclasshook__',
     '__weakref__',
     'a',
     'b']
    

    【讨论】:

    • 能否请您扩展您的答案?这太简短了,以至于有点不清楚。虽然我想我明白了,但我只是希望这个答案对其他人也有用。
    猜你喜欢
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多