Saya mencoba memahami cara kerja penggantian operator untuk dua operan dari kelas khusus.

Misalnya, misalkan saya memiliki yang berikut ini:

class Adder:
    def __init__(self, value=1):
        self.data = value
    def __add__(self,other):
        print('using __add__()')
        return self.data + other
    def __radd__(self,other):
        print('using __radd__()')
        return other + self.data

Saya menginisialisasi variabel berikut:

x = Adder(5)
y = Adder(4)

Dan kemudian lanjutkan untuk melakukan operasi berikut:

1 + x
using __radd__()
Out[108]: 6

x + 2
using __add__()
Out[109]: 7

Dua operasi di atas tampak lurus ke depan. Jika anggota kelas khusus saya berada di sebelah kanan "+" dalam ekspresi tambahan, maka __radd__ digunakan. Jika di sebelah kiri, maka __add__ digunakan. Ini berfungsi untuk ekspresi ketika satu operan bertipe Adder dan yang lainnya adalah yang lain.

Namun, ketika saya melakukan ini, saya mendapatkan hasil berikut:

x + y
using __add__()
using __radd__()
Out[110]: 9

Seperti yang Anda lihat, jika kedua operan adalah kelas khusus, maka __add__ dan __radd__ akan dipanggil.

Pertanyaan saya adalah bagaimana Python mengungkap situasi ini dan bagaimana ia dapat memanggil fungsi penambahan tangan kanan, serta fungsi penambahan tangan kiri.

0
MadPhysicist 9 Agustus 2017, 21:34

2 jawaban

Jawaban Terbaik

Itu karena di dalam metode Anda, Anda menambahkan data ke other. Ini sendiri merupakan turunan dari Adder. Jadi logikanya:

  • panggil __add__ di x;
  • tambahkan x.data (sebuah int) ke y (sebuah instance Adder)
  • ah, operan tangan kanan adalah instance dengan metode __radd__, jadi
  • panggil __radd__ pada y;
  • tambahkan int ke y.data (int lain).

Biasanya Anda akan memeriksa untuk melihat apakah other adalah turunan dari kelas Anda, dan jika demikian, tambahkan other.data daripada hanya other.

1
Daniel Roseman 9 Agustus 2017, 18:38

Itu karena implementasi metode __add__ dan __radd__ Anda tidak memberikan perlakuan khusus pada instance kelas Adder. Oleh karena itu, setiap panggilan __add__ mengarah ke operasi integer plus Adder instance yang selanjutnya memerlukan __radd__ karena instance Adder di sisi kanan.

Anda dapat menyelesaikan ini dengan melakukan:

def __add__(self, other):
    print('using __add__()')
    if isinstance(other, Adder):
        other = other.data
    return self.data + other

def __radd__(self, other):
    print('using __radd__()')
    return self.__add__(other)
1
Moses Koledoye 9 Agustus 2017, 18:46