Ini sepenuhnya tergantung pada objek i.
+=memanggil __iadd__metode (jika ada - mundur kembali __add__jika tidak ada) sedangkan +memanggil __add__metode 1 atau __radd__metode dalam beberapa kasus 2 .
Dari perspektif API, __iadd__seharusnya digunakan untuk memodifikasi objek yang bisa berubah di tempat (mengembalikan objek yang dimutasi) sedangkan __add__seharusnya mengembalikan contoh baru dari sesuatu. Untuk objek yang tidak dapat diubah , kedua metode mengembalikan instance baru, tetapi __iadd__akan menempatkan instance baru di namespace saat ini dengan nama yang sama dengan instance lama. Ini sebabnya
i = 1
i += 1
tampaknya meningkat i. Pada kenyataannya, Anda mendapatkan integer baru dan menetapkannya "di atas" i- kehilangan satu referensi ke integer lama. Dalam hal ini, i += 1persis sama dengan i = i + 1. Tapi, dengan sebagian besar objek yang bisa berubah, ini adalah cerita yang berbeda:
Sebagai contoh nyata:
a = [1, 2, 3]
b = a
b += [1, 2, 3]
print a #[1, 2, 3, 1, 2, 3]
print b #[1, 2, 3, 1, 2, 3]
dibandingkan dengan:
a = [1, 2, 3]
b = a
b = b + [1, 2, 3]
print a #[1, 2, 3]
print b #[1, 2, 3, 1, 2, 3]
pemberitahuan bagaimana dalam contoh pertama, karena bdan areferensi objek yang sama, ketika saya menggunakan +=pada b, itu benar-benar berubah b(dan amelihat perubahan itu juga - Setelah semua, itu referensi daftar yang sama). Namun dalam kasus kedua, ketika saya melakukannya b = b + [1, 2, 3], ini mengambil daftar yang bmereferensikan dan menyatukannya dengan daftar baru [1, 2, 3]. Itu kemudian menyimpan daftar gabungan di namespace saat ini sebagai b- Tanpa memperhatikan apa bbaris sebelumnya.
1 Dalam ekspresi x + y, jika x.__add__tidak diimplementasikan atau jika x.__add__(y)kembali NotImplemented dan xdan ymemiliki jenis yang berbeda , maka x + ycobalah menelepon y.__radd__(x). Jadi, dalam kasus di mana Anda miliki
foo_instance += bar_instance
jika Footidak menerapkan __add__atau __iadd__hasilnya di sini sama dengan
foo_instance = bar_instance.__radd__(bar_instance, foo_instance)
2 Dalam ekspresi foo_instance + bar_instance, bar_instance.__radd__akan dicoba sebelumnya foo_instance.__add__ jika jenisnya bar_instanceadalah subkelas dari jenis foo_instance(misalnya issubclass(Bar, Foo)). Rasional untuk ini adalah karena Bardalam beberapa arti "-tingkat yang lebih tinggi" objek dari Foosehingga Barharus mendapatkan pilihan utama Fooperilaku 's.
+=bertindak sepertiextend()dalam kasus daftar.