Untuk mendukung penetapan atribut arbitrer, sebuah objek membutuhkan a __dict__: a dict terkait dengan objek tersebut, di mana atribut arbitrer dapat disimpan. Jika tidak, tidak ada tempat untuk meletakkan atribut baru.
Sebuah contoh dari objecttidak tidak membawa sekitar __dict__- jika itu terjadi, sebelum mengerikan masalah ketergantungan melingkar (karena dict, seperti kebanyakan segalanya, mewarisi dariobject ;-), ini akan pelana setiap objek di Python dengan dict, yang berarti overhead dari banyak byte per objek yang saat ini tidak memiliki atau memerlukan dict (pada dasarnya, semua objek yang tidak memiliki atribut yang dapat ditetapkan secara sewenang-wenang tidak memiliki atau memerlukan dict).
Misalnya, menggunakan excellent pympler proyek yang (Anda bisa mendapatkannya melalui svn dari sini ), kita dapat melakukan beberapa pengukuran ...:
>>> from pympler import asizeof
>>> asizeof.asizeof({})
144
>>> asizeof.asizeof(23)
16
Anda tidak ingin setiap orang intmengambil 144 byte, bukan hanya 16, kan? -)
Sekarang, ketika Anda membuat kelas (mewarisi dari apa pun), banyak hal berubah ...:
>>> class dint(int): pass
...
>>> asizeof.asizeof(dint(23))
184
...itu __dict__ ini sekarang ditambahkan (ditambah, sedikit lebih overhead) - sehingga dintmisalnya dapat memiliki atribut sewenang-wenang, tetapi Anda membayar cukup biaya ruang untuk fleksibilitas itu.
Jadi bagaimana jika Anda menginginkan inthanya dengan satu atribut tambahan foobar...? Ini adalah kebutuhan yang langka, tetapi Python memang menawarkan mekanisme khusus untuk tujuan tersebut ...
>>> class fint(int):
... __slots__ = 'foobar',
... def __init__(self, x): self.foobar=x+100
...
>>> asizeof.asizeof(fint(23))
80
... tidak cukup sebagai kecil sebagai int, pikiran Anda! (atau bahkan keduanya int, satu selfdan satu self.foobar- yang kedua dapat dipindahkan), tapi pasti jauh lebih baik daripada a dint.
Ketika kelas memiliki __slots__atribut khusus (urutan string), maka classpernyataan (lebih tepatnya, metaclass default, type) tidak melengkapi setiap instance kelas itu dengan __dict__(dan karena itu kemampuan untuk memiliki atribut arbitrer), hanya terbatas , kumpulan "slot" yang kaku (pada dasarnya tempat yang masing-masing dapat menampung satu referensi ke beberapa objek) dengan nama yang diberikan.
Dalam pertukaran untuk fleksibilitas yang hilang, Anda mendapatkan banyak byte per contoh (mungkin bermakna hanya jika Anda memiliki zillions kasus berkeliaran di sekitar, tapi, ada yang menggunakan kasus untuk itu).
objecttidak dapat diubah dan atribut baru tidak dapat ditambahkan? Sepertinya ini yang paling masuk akal.