Mengapa Anda membutuhkan "diri". dalam Python untuk merujuk ke variabel instan?

13

Saya telah memprogram ke sejumlah bahasa seperti Java, Ruby, Haskell dan Python. Saya harus beralih di antara banyak bahasa per hari karena berbagai proyek yang saya kerjakan. Sekarang, masalahnya adalah saya sering lupa untuk menulis selfsebagai parameter pertama dalam definisi fungsi dalam Python yang sama adalah dengan memanggil metode pada objek yang sama.

Yang mengatakan, saya cukup kagum dengan pendekatan Python ini. Pada dasarnya kita harus mengetik lebih banyak untuk menyelesaikan sesuatu, dalam bahasa seperti Java dan Ruby hal-hal yang disederhanakan dengan secara otomatis merujuk variabel-variabel dalam objek saat ini.

Pertanyaan saya adalah mengapa ini selfperlu? Apakah ini murni pilihan gaya, atau adakah alasan mengapa Python tidak bisa membiarkan Anda menghilangkan selfcara Java dan C ++ membiarkan Anda menghilangkan this?

vivek
sumber
bacaan yang disarankan: Apa masalah dengan "Pro dan Kontra"?
Agak
1
@gnat sekarang hanya pro, dan serius itu pertanyaan bagus yang menggangguku sejak beberapa hari, tolong jangan membunuhnya dengan down voting.
vivek
2
Pertanyaan ini telah lebih dari sepenuhnya dibahas oleh stackoverflow.com/questions/2709821/… .
David Arno
Pemahaman saya adalah bahwa hal itu didasarkan pada gaya-C dari melewatkan pointer ke struct sebagai argumen pertama.
Dannnno
Menulis @staticmethodsebelum deklarasi metode, menekan kesalahan (hanya untuk info dan juga tidak disarankan)
Yash

Jawaban:

23

1) Mengapa selfdiperlukan sebagai parameter eksplisit dalam tanda tangan metode?

Karena metode adalah fungsi dan foo.bar(baz)hanya gula sintaksis bar(foo, baz). Kelas hanyalah kamus di mana beberapa nilai adalah fungsi. (Konstruktor juga hanya fungsi, itulah sebabnya Python tidak perlu new) Anda dapat mengatakan bahwa Python membuatnya eksplisit bahwa objek dibangun dari komponen yang lebih sederhana. Ini sesuai dengan filosofi "eksplisit lebih baik daripada implisit".

Sebaliknya, dalam Java objek benar-benar ajaib dan tidak dapat direduksi menjadi komponen yang lebih sederhana dalam bahasa. Di Jawa (setidaknya sampai Java 8) fungsi selalu merupakan metode yang dimiliki oleh objek, dan kepemilikan ini tidak dapat diubah karena sifat statis bahasa. Oleh karena itu tidak ada ambiguitas tentang apa yang thisdirujuk, jadi masuk akal untuk mendefinisikannya secara implisit.

JavaScript adalah contoh bahasa yang memiliki implisit thisseperti Java, tetapi di mana fungsi dapat ada secara terpisah dari objek seperti di Python. Hal ini menyebabkan banyak kebingungan tentang apa yang thismerujuk ketika fungsi-fungsi dilewatkan dan dipanggil dalam konteks yang berbeda. Banyak yang secara naluriah berpikir thisharus mengacu pada beberapa sifat intrinsik dari fungsi tersebut, sementara itu sebenarnya murni ditentukan oleh cara fungsi itu disebut. Saya percaya memiliki thissebagai parameter eksplisit seperti di Python akan membuat ini jauh lebih membingungkan.

Beberapa manfaat lain dari selfparameter- eksplisit :

  • Dekorator hanyalah fungsi yang membungkus fungsi lainnya. Karena metode hanyalah fungsi, dekorator berfungsi dengan baik pada metode. Jika ada semacam diri tersirat, dekorator tidak akan bekerja secara transparan pada metode.

  • Metode metode dan statis tidak mengambil parameter instance. Metode kelas mengambil kelas sebagai argumen pertama (biasanya disebut cls). Parameter selfatau eksplisit clsmembuatnya lebih jelas apa yang sedang terjadi, dan apa yang Anda memiliki akses ke dalam metode.

2) Mengapa instance instance harus memenuhi syarat dengan " self.?

Di Jawa, Anda tidak perlu membuat awalan variabel anggota dengan " this.", tetapi dengan Python " self." selalu diperlukan. Alasannya adalah bahwa Python tidak memiliki sintaksis eksplisit untuk mendeklarasikan variabel, sehingga tidak akan ada cara untuk mengetahui apakah x = 7seharusnya mendeklarasikan variabel lokal baru atau menetapkan ke variabel anggota. Menentukan self.memecahkan ambiguitas ini.

JacquesB
sumber
Referensi variabel anggota implisit (tanpa self., seperti Java) pada dasarnya tidak kompatibel dengan aturan pelingkupan dan ketika Anda perlu secara eksplisit di sana, menjadi tersirat tentang parameter tidak masuk akal lagi.
Jan Hudec
@ JanHudec: Bagus, benar. Saya telah menambahkannya ke jawabannya.
JacquesB
6

Ada alasan yang agak sederhana bahwa AFAIK belum benar-benar disentuh dalam duplikat lintas-situs, atau di sini: Python dimulai sebagai bahasa prosedural. Itu didasarkan pada ABC, juga bahasa prosedural.

Object-Orientation ditambahkan kemudian, dan ketika ditambahkan, Guido van Rossum ingin menambahkan jumlah fitur minimal yang mungkin, agar desain Python tetap sederhana. Python sudah memiliki dictfungsi dan s, jadi mengapa menambahkan sesuatu yang sama sekali baru ke bahasa, ketika sebuah objek hanya bisa menjadi dictslot dan kelas hanya bisa menjadi dictfungsi? Metode dapat diartikan sebagai fungsi yang diterapkan sebagian yang menutup satu argumen tunggal. Dan itulah tepatnya metode diimplementasikan dalam Python: tidak. Mereka hanya fungsi yang menerima argumen istimewa.

Jörg W Mittag
sumber
Saya percaya Python mendukung OO dan memiliki kelas dan warisan dari versi pertama yang dirilis. Setidaknya inilah yang dikatakan wikipedia kepada saya. Tetapi proses van Rossums pada awalnya merancang bahasa mungkin seperti yang Anda gambarkan.
JacquesB
Terima kasih atas tautannya, ini bacaan yang sangat menarik.
JacquesB
2

Berikut adalah kesimpulan saya berdasarkan atas jawaban dan membaca Guido sendiri bertele-tele tentang topik ini:

Ide besar

Fungsi adalah blok bangunan penting dalam Python (atau kita harus mengatakan satu-satunya), pada kenyataannya kita adalah jenis meniru OOP dengan menggunakan fungsi.

Mengingat bahwa suatu kelas tidak lain hanyalah kamus fungsi, maka kita dapat melampirkan fungsi apa pun ke kelas mana pun pada saat run time. Pada dasarnya itu adalah karena kebutuhan ini untuk melemparkan fungsi-fungsi sekitar pada saat run time kita dapat melakukan hal-hal seperti Monkey Patching . Di sini selfparameter yang mendukung polimorfisme parametrik.

vivek
sumber
1
Pertanyaan yang dijawab sendiri didorong ketika jawaban Anda adalah jawaban yang berkualitas tinggi. Ketika saya membandingkan jawaban Anda di sini dengan jawaban lainnya, saya bertanya-tanya mengapa Anda merasa perlu menambahkan ini. Jawaban lain masuk lebih dalam dan menambahkan lebih detail daripada apa jawaban Anda.
1
@ GlenH7 jawabannya hanya untuk referensi saya karena setiap kali saya tidak bisa datang dan membaca jawaban semua orang lagi dan lagi. Mengenai kualitas, beri tahu saya jika ada sedikit informasi yang menyesatkan. Bagaimanapun, saya biasanya menunggu 2-3 hari untuk menerima jawaban.
vivek
Down voting menjadi mata uang murah dan semua orang di sini membelanjakannya dengan kedua tangan tanpa mengetahui artinya. Apakah Anda menyadari jika seseorang datang ke sini melihat jawaban ini memilih akan menganggap itu salah!
vivek