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 object
tidak 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 int
mengambil 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 dint
misalnya dapat memiliki atribut sewenang-wenang, tetapi Anda membayar cukup biaya ruang untuk fleksibilitas itu.
Jadi bagaimana jika Anda menginginkan int
hanya 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 self
dan satu self.foobar
- yang kedua dapat dipindahkan), tapi pasti jauh lebih baik daripada a dint
.
Ketika kelas memiliki __slots__
atribut khusus (urutan string), maka class
pernyataan (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).
object
tidak dapat diubah dan atribut baru tidak dapat ditambahkan? Sepertinya ini yang paling masuk akal.