Пустой размер класса в python

Я просто пытаюсь узнать обоснование размера пустого класса в python, на С++, поскольку каждый знает, что размер пустого класса всегда будет показывать 1 байт (насколько я видел) это позволяет времени выполнения создавать уникальный объект, и я пытаюсь выяснить, какой размер пустого класса в python:

class Empty:pass # i hope this will create empty class

и когда я делаю

import sys
print ("show",sys.getsizeof(Empty)) # i get 1016

Интересно, почему Empty занимает много 1016 (байтов)? а также возвращает ли значение (1016) это стандартное значение, которое никогда не изменяется (в основном), как С++?, Ожидаем ли мы оптимизации нулевого базового класса из интерпретатора python? Есть ли способ уменьшить размер am Empty ( просто ради любопытства)?

Ответ 1

Я предполагаю, что вы используете 64-разрядную версию Python 3. На 32-битном Python 3.6 (в Linux) ваш код печатает show 508.

Однако, что размер самого объекта класса, который наследует довольно много вещей из базового класса object. Если вместо этого вы получите размер экземпляра вашего класса, результат будет намного меньше. В моей системе

import sys

class Empty(object):
    pass

print("show", sys.getsizeof(Empty()))

Выход

show 28

что намного более компактно.:)

FWIW, на Python 2.6.6, sys.getsizeof(Empty) возвращает 448 для класса нового стиля и нечеткий 44 для класса старого стиля (тот, который не наследует от object). sys.getsizeof(Empty()) возвращает 28 для экземпляра класса нового стиля и 32 для старого стиля.


Вы можете уменьшить размер экземпляра, используя __slots__

Эта переменная класса может быть назначена строка, итерабельность или последовательность строки с именами переменных, используемые экземплярами. __slots__ резервы пространство для объявленных переменных и предотвращает автоматическое создание __dict__ и __weakref__ для каждого экземпляра.

import sys

class Empty(object):
    __slots__ = []

print("show", sys.getsizeof(Empty()))

Выход

show 8

Пожалуйста, прочитайте документы, чтобы понять, как использовать эту функцию.

Ответ 2

Python 2.7.11 (default, Apr 12 2016, 14:09:35) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin
>>> class Empty:pass
>>> import sys
>>> print ("show",sys.getsizeof(Empty)) # i get 1016
('show', 104)
>>> print ("show",sys.getsizeof(Empty()))
('show', 72)

Не 1016 байт. Как вы можете видеть, это специфическая реализация. Другие интересные размеры, используя классы нового стиля:

>>> print ("show",sys.getsizeof(object())) 
('show', 16)
>>> class Empty2(object):pass
>>> print ("show",sys.getsizeof(Empty2)) 
('show', 904)
>>> print ("show",sys.getsizeof(Empty2())) 
('show', 64)

Пустое определение класса по-прежнему является определением класса и, следовательно, объектом класса (подробнее здесь):

Когда введено определение класса, создается новое пространство имен и используется в качестве локальной области.

Когда определение класса остается в порядке (через конец), создается объект класса. Это в основном оболочка вокруг содержимого пространство имен, созданное определением класса...

Все объекты класса имеют минимальный набор атрибутов, которые вы видите:

    >>> dir(Empty)
['__doc__', '__module__']
>>> dir(Empty2)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

А также другие детали реализации, которые являются причиной их большего, чем наивно ожидаемый размер.

Наконец, обратите внимание, что экземпляры класса действительно довольно малы, как и ожидалось, и не такие большие, как объекты класса. Empty - объект класса. Empty() - это экземпляр класса.