Почему подклассы примитивных типов занимают больше памяти в Python? - PullRequest
0 голосов
/ 31 января 2019

Я пытаюсь создать подкласс примитивных типов в Python следующим образом (упрощенная версия):

class MyInt(int):
    pass

Я думал, что объект этого класса будет занимать столько же памяти, что и примитивный.Но, по-видимому, это не так:

import sys
sys.getsizeof(10)          # 24
sys.getsizeof(MyInt(10))   # 72

Используя __slots__, я смог сохранить немного памяти, но подкласс все еще занимает больше места:

class MyInt(int):
    __slots__ = ()


sys.getsizeof(10)          # 24
sys.getsizeof(MyInt(10))   # 56

Если я подклассмои собственные классы, с другой стороны, используют то же самое использование памяти:

class Father(object):
    pass


class Son(Father):
    pass

sys.getsizeof(Father())  # 64
sys.getsizeof(Son())     # 64
  1. Почему объект подтипа использует больше памяти, чем объект примитивного типа, если нет дополнительных полей?
  2. Есть ли способ предотвратить (или минимизировать) это?

Я использую Python 2.7.12.

1 Ответ

0 голосов
/ 09 февраля 2019

Подклассы встроенных классов были возможны только в Python, когда в Python 2.2 были созданы «новые классы стилей».Таким образом, не глядя на код и не читая внимательно заметки к презентации в этой статье Гвидо , можно сделать вывод, что в Python2 необходимы некоторые типовые внутренние поля, чтобы разрешить встроенные классы (в которых был свой кодбаза написана до объединения), чтобы работать и вести себя хорошо, как "пользовательские классы", когда подклассы.(Это поведение "объекта", которое не является встроенным в кодовую базу для объектов "старого стиля" и "int").

Все, что происходит, находится где-то внутри Python 2.7 Objects/typeobject.c - так что вы можете взглянуть туда (или подождать, пока кто-то, кто может легче проанализировать, что придет с другим ответом)

Что, как упоминает @blownhither_ma в комментариях выше, похоже, больше не относится к Python3 - я бы сказал, что объединение классов консолидируется с 2009 года:

In [158]: from sys import getsizeof as sizeof

In [159]: sizeof(int())
Out[159]: 24

In [160]: class MInt(int):
     ...:     __slots__ = ()
     ...:     

In [161]: sizeof(MInt())
Out[161]: 24

Итак, покаЕсть вопросы, на которые еще предстоит ответить на ваш вопрос, они имеют значение только для Python 2, который сейчас никто не должен использовать в новом коде.

...