Saat mendefinisikan metode pada kelas dengan Python, tampilannya seperti ini:
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
Tetapi dalam beberapa bahasa lain, seperti C #, Anda memiliki referensi ke objek yang terikat metode dengan kata kunci "ini" tanpa menyatakannya sebagai argumen dalam prototipe metode.
Apakah ini keputusan desain bahasa yang disengaja dalam Python atau ada beberapa detail implementasi yang memerlukan pengesahan "diri" sebagai argumen?
self
untuk mengakses anggota - stackoverflow.com/questions/910020/…Jawaban:
Saya suka mengutip Peters 'Zen of Python. "Eksplisit lebih baik daripada implisit."
Di Java dan C ++, '
this.
' dapat disimpulkan, kecuali bila Anda memiliki nama variabel yang membuatnya tidak mungkin untuk disimpulkan. Jadi, terkadang Anda membutuhkannya dan terkadang tidak.Python memilih untuk membuat hal-hal seperti ini eksplisit daripada berdasarkan aturan.
Selain itu, karena tidak ada yang tersirat atau diasumsikan, bagian dari implementasi diekspos.
self.__class__
,self.__dict__
dan struktur "internal" lainnya tersedia dengan cara yang jelas.sumber
Ini untuk meminimalkan perbedaan antara metode dan fungsi. Ini memungkinkan Anda untuk dengan mudah menghasilkan metode dalam metaclasses, atau menambahkan metode saat runtime ke kelas yang sudah ada.
misalnya
Itu juga (sejauh yang saya tahu) membuat implementasi runtime python lebih mudah.
sumber
self
dalam deklarasi fungsi (ingatlah, mungkin ini melempar batu dari rumah kaca, karena JavaScript memiliki beberapathis
semantik mengikat yang cukup rumit )Saya menyarankan agar seseorang membaca blog Guido van Rossum tentang topik ini - Mengapa diri eksplisit harus tetap ada .
sumber
Python tidak memaksa Anda untuk menggunakan "diri". Anda dapat memberikan nama apa pun yang Anda inginkan. Anda hanya perlu mengingat bahwa argumen pertama dalam header definisi metode adalah referensi ke objek.
sumber
@staticmethod
itu tidak.Juga memungkinkan Anda untuk melakukan ini: (singkatnya, memohon
Outer(3).create_inner_class(4)().weird_sum_with_closure_scope(5)
akan mengembalikan 12, tetapi akan melakukannya dengan cara yang paling gila.Tentu saja, ini lebih sulit untuk dibayangkan dalam bahasa seperti Java dan C #. Dengan membuat referensi diri eksplisit, Anda bebas untuk merujuk ke objek apa pun dengan referensi diri itu. Selain itu, cara bermain dengan kelas saat runtime lebih sulit dilakukan dalam bahasa yang lebih statis - bukan berarti itu baik atau buruk. Hanya saja diri yang eksplisit memungkinkan semua kegilaan ini ada.
Selain itu, bayangkan ini: Kami ingin menyesuaikan perilaku metode (untuk profil, atau sihir hitam gila). Ini dapat membuat kita berpikir: bagaimana jika kita memiliki kelas
Method
yang perilakunya dapat kita atur atau kendalikan?Nah ini dia:
Dan sekarang:
InnocentClass().magic_method()
akan bertindak seperti yang diharapkan. Metode ini akan diikat denganinnocent_self
parameter keInnocentClass
, dan denganmagic_self
ke instance MagicMethod. Aneh ya? Ini seperti memiliki 2 kata kuncithis1
danthis2
dalam bahasa seperti Java dan C #. Sihir seperti ini memungkinkan kerangka kerja untuk melakukan hal-hal yang seharusnya jauh lebih bertele-tele.Sekali lagi, saya tidak ingin mengomentari etika dari hal ini. Saya hanya ingin menunjukkan hal-hal yang akan lebih sulit dilakukan tanpa referensi diri yang eksplisit.
sumber
OuterClass.this
untuk mendapatkan 'diri' dari kelas luar, tetapi Anda masih dapat menggunakanthis
sebagai referensi untuk dirinya sendiri; sangat mirip dengan apa yang Anda lakukan di sini di Python. Bagi saya tidak sulit membayangkan ini. Mungkin itu tergantung pada kemahiran seseorang dalam bahasa yang bersangkutan?Something
, yang pada gilirannya didefinisikan di dalam implementasi anonim lainnyaSomething
? Dalam python tentu saja Anda bisa merujuk ke salah satu cakupan.this
. Referensi implisit tidak mungkin di Jawa.this
hasilnya. MisalnyaObject self1 = this;
(baik menggunakan Object, atau sesuatu yang kurang generik). Kemudian, jika Anda memiliki akses ke variabel dalam lingkup yang lebih tinggi, Anda bisa memiliki akses keself1
,self2
, ...selfn
. Saya pikir ini harus dinyatakan final atau sesuatu, tetapi mungkin berhasil.Saya pikir alasan sebenarnya selain "The Zen of Python" adalah bahwa Functions adalah warga negara kelas satu di Python.
Yang pada dasarnya menjadikan mereka sebagai Obyek. Sekarang Masalah mendasarnya adalah jika fungsi Anda juga objek, dalam paradigma berorientasi objek bagaimana Anda mengirim pesan ke Objek ketika pesan itu sendiri adalah objek?
Tampak seperti masalah telur ayam, untuk mengurangi paradoks ini, satu-satunya cara yang mungkin adalah dengan melewatkan konteks eksekusi ke metode atau mendeteksinya. Tetapi karena python dapat memiliki fungsi bersarang, tidak mungkin melakukannya karena konteks eksekusi akan berubah untuk fungsi dalam.
Ini berarti satu-satunya solusi yang mungkin adalah secara eksplisit melewati 'diri' (Konteks eksekusi).
Jadi saya percaya ini adalah masalah implementasi Zen yang datang jauh kemudian.
sumber
Saya pikir itu ada hubungannya dengan PEP 227:
sumber
Seperti yang dijelaskan dalam diri sendiri dengan Python, Demystified
Doa:
init () mendefinisikan tiga parameter tetapi kami baru saja melewati dua (6 dan 8). Demikian pula jarak () membutuhkan satu tetapi nol argumen disahkan.
Mengapa Python tidak mengeluh tentang ketidakcocokan nomor argumen ini ?
sumber
Ada juga jawaban lain yang sangat sederhana: menurut zen dari python , "eksplisit lebih baik daripada implisit".
sumber