Пустой размер класса в 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()
- это экземпляр класса.