Pertama-tama A.__dict__.__dict__berbeda dari A.__dict__['__dict__'], dan yang pertama tidak ada. Yang terakhir adalah __dict__atribut yang dimiliki oleh instance kelas. Ini adalah objek deskriptor yang mengembalikan kamus internal atribut untuk instance tertentu. Singkatnya, __dict__atribut suatu objek tidak dapat disimpan dalam objek __dict__, jadi itu diakses melalui deskriptor yang ditentukan di kelas.
Untuk memahami ini, Anda harus membaca dokumentasi protokol deskriptor .
Versi singkatnya:
- Untuk instance kelas
A, akses ke instance.__dict__disediakan oleh A.__dict__['__dict__']yang sama dengan vars(A)['__dict__'].
- Untuk kelas A, akses ke
A.__dict__disediakan oleh type.__dict__['__dict__'](secara teori) yang sama dengan vars(type)['__dict__'].
Versi panjang:
Baik kelas maupun objek menyediakan akses ke atribut baik melalui operator atribut (diimplementasikan melalui kelas atau metaclass __getattribute__), dan __dict__atribut / protokol yang digunakan oleh vars(ob).
Untuk objek normal, __dict__objek membuat objek terpisah dict, yang menyimpan atribut, dan __getattribute__pertama kali mencoba mengaksesnya dan mendapatkan atribut dari sana (sebelum mencoba mencari atribut di kelas dengan memanfaatkan protokol deskriptor, dan sebelum memanggil __getattr__). The __dict__descriptor pada kelas mengimplementasikan akses ke kamus ini.
x.namesetara dengan mencoba mereka dalam rangka: x.__dict__['name'], type(x).name.__get__(x, type(x)),type(x).name
x.__dict__ melakukan hal yang sama tetapi melewatkan yang pertama karena alasan yang jelas
Seperti tidak mungkin untuk __dict__dari instanceuntuk disimpan dalam __dict__instance, itu diakses melalui protokol deskriptor langsung sebaliknya, dan disimpan dalam bidang khusus dalam hal ini.
Skenario serupa berlaku untuk kelas, meskipun mereka __dict__adalah objek proxy khusus yang berpura-pura menjadi kamus (tetapi mungkin tidak secara internal), dan tidak memungkinkan Anda untuk mengubahnya atau menggantinya dengan yang lain. Proksi ini memungkinkan Anda, di antara yang lainnya, untuk mengakses atribut kelas yang khusus untuk itu, dan tidak ditentukan di salah satu basisnya.
Secara default, vars(cls)kelas kosong membawa tiga deskriptor - __dict__untuk menyimpan atribut instance, __weakref__yang digunakan secara internal oleh weakref, dan docstring kelas. Dua yang pertama mungkin hilang jika Anda menentukan __slots__. Maka Anda tidak akan memiliki __dict__dan __weakref__atribut, tetapi Anda akan memiliki atribut kelas tunggal untuk setiap slot. Atribut instance tidak akan disimpan dalam kamus, dan akses ke sana akan disediakan oleh deskriptor masing-masing di kelas.
Dan terakhir, ketidakkonsistenan yang A.__dict__berbeda dari A.__dict__['__dict__']adalah karena atribut __dict__, dengan pengecualian, tidak pernah dicari vars(A), jadi apa yang benar karena itu tidak benar untuk hampir semua atribut lain yang Anda gunakan. Misalnya, A.__weakref__sama saja dengan A.__dict__['__weakref__']. Jika ketidakkonsistenan ini tidak ada, penggunaan A.__dict__tidak akan berhasil, dan Anda harus selalu menggunakannya vars(A).
ive. Setidaknya itu akan membuat ini menjadiA.__dict__['ive']pertanyaan lagi ;) Saya akan melihat diri saya keluar