3

I recently explained a friend the usage of __slots__. I wanted to demonstrate the result to him and used the following code:

import sys


class Foo:
    __slots__ = 'a', 'b'

    def __init__(self, a, b):
        self.a = a
        self.b = b


class Bar:
    def __init__(self, a, b):
        self.a = a
        self.b = b


a = Foo(10, 20)
b = Bar(10, 20)

print(sys.getsizeof(a))
print(sys.getsizeof(b))

The output on the console for Python 3 was:

 56
 56

The output for Python 2 was:

 72
 72

Why is there no difference in size?

exhuma
  • 20,071
  • 12
  • 90
  • 123
  • Perhaps not a duplicate, but related: http://stackoverflow.com/questions/11301295/measure-object-size-accurately-in-python-sys-getsizeof-not-functioning – BrenBarn May 18 '16 at 06:47

2 Answers2

2

For Python2, you'll need to inherit from object to activate the __slots__ machinery

The problem is that you are comparing apples with oranges.

sys.getsizeof is only a shallow size, ie. it's doesn't calculate the size of all the interior objects.

for the __slots__ version, you will see it is proportional to the number of slots

for the normal object, you should look at the size of the instance __dict__ to make a reasonable comparison.

Another approach is to allocate a few million of these objects and see how much memory the operating system reports as used.

John La Rooy
  • 295,403
  • 53
  • 369
  • 502
1

John La Rooy's observation is correct that sys.getsizeof is shallow and therefore doesn't give the correct result. Using pympler's asizeof module you can see there is a different answer:

from pympler import asizeof

class Foo:
    __slots__ = 'a', 'b'

    def __init__(self, a, b):
        self.a = a
        self.b = b


class Bar:
    def __init__(self, a, b):
        self.a = a
        self.b = b


x = Foo(10, 20)
y = Bar(10, 20)

print(asizeof.asizeof(x))
print(asizeof.asizeof(y))

Running:

python3 test.py

gives:

192
328
Dair
  • 15,910
  • 9
  • 62
  • 107