Для поддержки произвольного назначения атрибутов объекту необходим __dict__
: a dict, связанный с объектом, в котором могут храниться произвольные атрибуты. Иначе новые атрибуты некуда ставить .
Экземпляр object
вовсе не носить с собой __dict__
- если это так, перед ужасной круговой задачей зависимости (так dict
, как и большинство всего остального, наследуется от object
;-), это было бы оседлать каждый объект в Python с Dict, что означало бы накладные расходы из многих байт на объект , который в настоящее время не имеет или не нуждается в Dict ( по существу, все объекты , которые не имеют произвольно назначаемые атрибуты не имеют или нужен Dict).
Например, используя отличный pympler
проект (вы можете получить его через svn отсюда ), мы можем провести некоторые измерения ...:
>>> from pympler import asizeof
>>> asizeof.asizeof({})
144
>>> asizeof.asizeof(23)
16
Вы же не хотите, чтобы каждый int
занимал 144 байта вместо 16, верно? -)
Теперь, когда вы создаете класс (наследующий от чего угодно), все меняется ...:
>>> class dint(int): pass
...
>>> asizeof.asizeof(dint(23))
184
... __dict__
будет теперь добавлены (плюс немного больше накладных расходов) - так dint
экземпляр может иметь произвольные атрибуты, но вы платите довольно стоимость пространства для этой гибкости.
Так что, если вы хотите int
s с одним дополнительным атрибутом foobar
...? Это редкая необходимость, но Python предлагает специальный механизм для этой цели ...
>>> class fint(int):
... __slots__ = 'foobar',
... def __init__(self, x): self.foobar=x+100
...
>>> asizeof.asizeof(fint(23))
80
... не совсем , как крошечное как int
, заметьте! (или даже два int
s, one the self
и one the self.foobar
- второй можно переназначить), но, безусловно, намного лучше, чем a dint
.
Когда у класса есть __slots__
специальный атрибут (последовательность строк), то class
оператор (точнее, метакласс по умолчанию type
) не снабжает каждый экземпляр этого класса __dict__
(и, следовательно, возможностью иметь произвольные атрибуты), а только конечным , жесткий набор «слотов» (в основном мест, каждая из которых может содержать одну ссылку на какой-либо объект) с заданными именами.
Взамен утраченной гибкость, вы получите много байт на экземпляр (возможно , имеет смысл только если у вас есть несметное экземпляров gallivanting вокруг, но там есть случаи использование для этого).
object
тип неизменен, и нельзя добавлять новые атрибуты? В этом есть смысл.