Ada dua hal yang terlibat di sini:
1. class attributes and instance attributes
2. difference between the operators + and += for lists
+operator memanggil __add__metode tersebut pada daftar. Ini mengambil semua elemen dari operannya dan membuat daftar baru yang berisi elemen-elemen yang menjaga urutannya.
+=__iadd__metode panggilan operator pada daftar. Dibutuhkan iterable dan menambahkan semua elemen dari iterable ke daftar di tempatnya. Itu tidak membuat objek daftar baru.
Di kelas foopernyataan self.bar += [x]tersebut bukanlah pernyataan tugas tetapi sebenarnya diterjemahkan menjadi
self.bar.__iadd__([x]) # modifies the class attribute
yang mengubah daftar di tempat dan bertindak seperti metode daftar extend.
Sebaliknya foo2, di kelas , pernyataan tugas dalam initmetode
self.bar = self.bar + [x]
dapat didekonstruksi sebagai:
Instance ini tidak memiliki atribut bar(meskipun demikian, ada atribut kelas dengan nama yang sama) sehingga ia mengakses atribut kelas bardan membuat daftar baru dengan menambahkannya x. Pernyataan itu diterjemahkan menjadi:
self.bar = self.bar.__add__([x]) # bar on the lhs is the class attribute
Kemudian itu membuat atribut instance bardan menetapkan daftar yang baru dibuat ke dalamnya. Perhatikan bahwa bardi rhs tugas berbeda dari bardi lhs.
Untuk contoh kelas foo, baradalah atribut kelas dan bukan atribut contoh. Karenanya setiap perubahan pada atribut kelas barakan tercermin untuk semua contoh.
Sebaliknya, setiap instance kelas foo2memiliki atribut instance sendiri-sendiri baryang berbeda dengan atribut kelas yang bernama sama bar.
f = foo2(4)
print f.bar # accessing the instance attribute. prints [4]
print f.__class__.bar # accessing the class attribute. prints []
Semoga ini membereskan semuanya.