Why does __slots__ = ('__dict__',) create smaller instances?

class Spam(object):
    __slots__ = ('__dict__',)

Produces instances smaller than those that have a "normal" class. Why is this?

Source: David Basley recent tweet .

+4
source share
1 answer

It seems to me that memory saving is due to the lack __weakref__of an instance.

So, if we have:

class Spam1(object):
    __slots__ = ('__dict__',)

class Spam2(object):
    __slots__ = ('__dict__', '__weakref__')

class Spam3(object):
    __slots__ = ('foo',)

class Eggs(object):
    pass

objs = Spam1(), Spam2(), Spam3(), Eggs()
for obj in objs:
    obj.foo = 'bar'

import sys
for obj in objs:
    print(type(obj).__name__, sys.getsizeof(obj))

Results (on python 3.5.2):

Spam1 48
Spam2 56
Spam3 48
Eggs 56

We see that Spam2(which has __weakref__) is the same size as Eggs(the traditional class).

, ( ). , __slots__ , __dict__ . __dict__ ( - O (1) //), , , , '__dict__' __slots__, ( ).

, :

class Spam3(object):
    __slots__ = ('foo', 'bar')

, , , :

Spam1 48
Spam2 56
Spam3 56
Eggs 56

, 8 ( - , 8 sizeof(pointer) ). , __slots__ ( , ). , ( __slots__, dir(instance)), __slots__). .

, ... . :

class Foo(object):
    __slots__ = ('foo',)
    foo = 'bar'

, :

  • "" .
  • __slots__ = ('__dict__',) __dict__ __weakref__
  • __slots__ = ('__dict__',) __dict__, __weakref__.
  • __slots__ . ( dir(instance)).
  • , __slots__ , , . __slots__ , dict ( dict , , , - ). , (, ).
+7

Source: https://habr.com/ru/post/1657519/


All Articles