Aby obsłużyć przypisanie dowolnego atrybutu, obiekt potrzebuje a __dict__: dict skojarzonego z obiektem, w którym można przechowywać dowolne atrybuty. W przeciwnym razie nie ma gdzie umieścić nowych atrybutów.
Instancja objectma nie nosić ze sobą __dict__- gdyby tak się stało, przed strasznym okrągłym problemu uzależnienia (ponieważ dict, jak większość wszystko inne, dziedziczy od object;-) byłoby to siodło każdy obiekt w Pythonie z dict, co oznaczałoby obciążenie z wielu bajtów na obiekt, który obecnie nie ma lub nie potrzebuje dyktowania (zasadniczo wszystkie obiekty, które nie mają przypisywalnych atrybutów, nie mają ani nie potrzebują dyktowania).
Na przykład, korzystając z doskonałego pymplerprojektu (możesz go pobrać przez svn stąd ), możemy wykonać kilka pomiarów ...:
>>> from pympler import asizeof
>>> asizeof.asizeof({})
144
>>> asizeof.asizeof(23)
16
Nie chciałbyś, aby każdy intzajmował 144 bajty zamiast tylko 16, prawda? -)
Teraz, kiedy tworzysz klasę (dziedzicząc po czymkolwiek), rzeczy się zmieniają ...:
>>> class dint(int): pass
...
>>> asizeof.asizeof(dint(23))
184
... __dict__ jest teraz dodawany (plus trochę więcej narzutu) - więc dintinstancja może mieć dowolne atrybuty, ale za taką elastyczność płacisz sporo miejsca.
A co by było, gdybyś chciał mieć inttylko jeden dodatkowy atrybut foobar...? Jest to rzadka potrzeba, ale Python oferuje specjalny mechanizm do tego celu ...
>>> class fint(int):
... __slots__ = 'foobar',
... def __init__(self, x): self.foobar=x+100
...
>>> asizeof.asizeof(fint(23))
80
... nie dość jak mały jako int, przeszkadza ci! (lub nawet dwa ints, jeden selfi jeden self.foobar- drugi można ponownie przypisać), ale z pewnością znacznie lepszy niż dint.
Gdy klasa ma __slots__atrybut specjalny (sekwencję ciągów), to classinstrukcja (a dokładniej domyślna metaklasa type) nie wyposaża każdej instancji tej klasy w __dict__atrybut (a tym samym możliwość posiadania dowolnych atrybutów), tylko skończoną , sztywny zbiór "szczelin" (w zasadzie miejsc, które mogą zawierać jedno odniesienie do jakiegoś obiektu) o podanych nazwach.
W zamian za utratę elastyczności zyskujesz dużo bajtów na instancję (prawdopodobnie ma to znaczenie tylko wtedy, gdy masz zyliony instancji kręcących się po okolicy, ale są do tego przypadki użycia).
objecttyp jest niezmienny i nie można dodawać nowych atrybutów? Wydaje się, że miałoby to największy sens.