Для підтримки довільного присвоєння атрибутів об'єкту потрібно __dict__: 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 екземпляр може мати довільні атрибути, але ви платите досить вартість простору для цієї гнучкості.
Так що, якби ви хотіли ints лише з одним додатковим атрибутом foobar...? Це рідкісна потреба, але Python пропонує спеціальний механізм для цієї мети ...
>>> class fint(int):
... __slots__ = 'foobar',
... def __init__(self, x): self.foobar=x+100
...
>>> asizeof.asizeof(fint(23))
80
... не зовсім такий крихітний, як int, зауважте! (або навіть два ints, один the selfта one the self.foobar- другий може бути перепризначений), але, безумовно, набагато кращий ніжdint .
Коли клас має __slots__спеціальний атрибут (послідовність рядків), тоді classоператор (точніше, метаклас за замовчуванням, type) робить НЕ оснащувати кожен екземпляр цього класу з __dict__(і , отже , можливістю мати довільні атрибути), тільки кінцевий , жорсткий набір "слотів" (в основному місця, кожна з яких може містити одне посилання на якийсь об'єкт) із заданими іменами.
В обмін на втрачену гнучкість ви отримуєте багато байтів на екземпляр (можливо, значущий лише у тому випадку, якщо навколо вас мільйони екземплярів, які галівантують, але для цього існують випадки використання).
objectтип незмінний, і нові атрибути не можна додавати? Здається, це мало би найбільший сенс.