Saya menggunakan itu di Objective-C saya punya konstruk ini:
- (void)init {
if (self = [super init]) {
// init class
}
return self;
}
Haruskah Python juga memanggil implementasi kelas induk untuk __init__
?
class NewClass(SomeOtherClass):
def __init__(self):
SomeOtherClass.__init__(self)
# init class
Apakah ini juga benar / salah untuk __new__()
dan __del__()
?
Sunting: Ada pertanyaan yang sangat mirip: Inheritance and Overriding __init__
in Python
python
oop
superclass
Georg Schölly
sumber
sumber
object
adalah kesalahan ketik. Tetapi sekarang Anda bahkan tidak memilikisuper
judul yang merujuk pada pertanyaan Anda.Jawaban:
Dalam Python, memanggil kelas-super '
__init__
adalah opsional. Jika Anda menyebutnya, maka juga opsional apakah menggunakansuper
pengidentifikasi, atau apakah akan secara eksplisit memberi nama kelas super:Dalam kasus objek, memanggil metode super tidak sepenuhnya diperlukan, karena metode super kosong. Sama untuk
__del__
.Di sisi lain, untuk
__new__
, Anda memang harus memanggil metode super, dan menggunakan kembalinya sebagai objek yang baru dibuat - kecuali jika Anda secara eksplisit ingin mengembalikan sesuatu yang berbeda.sumber
[super init]
itu, itu akan lebih umum. Hanya pemikiran spekulatif; konstruksi super dengan Python 2.x agak canggung bagi saya.Jika Anda memerlukan sesuatu dari super
__init__
untuk dilakukan selain apa yang sedang dilakukan di kelas saat ini,__init__,
Anda harus menyebutnya sendiri, karena itu tidak akan terjadi secara otomatis. Tetapi jika Anda tidak membutuhkan apa pun dari super__init__,
tidak perlu menyebutnya. Contoh:__del__
adalah cara yang sama, (tapi hati-hati mengandalkan__del__
untuk finalisasi - pertimbangkan melakukannya melalui dengan pernyataan sebagai gantinya).Saya jarang menggunakan
__new__.
saya melakukan semua inisialisasi di__init__.
sumber
super(D,self).__init__()
Dalam jawaban Anon:
"Jika Anda perlu sesuatu dari super
__init__
untuk dilakukan selain apa yang sedang dilakukan di kelas saat ini__init__
, Anda harus menyebutnya sendiri, karena itu tidak akan terjadi secara otomatis"Sungguh luar biasa: dia mengatakan persis kebalikan dari prinsip pewarisan.
Bukannya bahwa "sesuatu dari super
__init__
(...) tidak akan terjadi secara otomatis" , itu bahwa itu AKAN terjadi secara otomatis, tetapi itu tidak terjadi karena kelas-dasar '__init__
ditimpa oleh definisi dari turunan-clas__init__
Jadi, MENGAPA mendefinisikan diturunkan_klas '
__init__
, karena itu menimpa apa yang ditujukan ketika seseorang resor untuk warisan ??Itu karena seseorang perlu mendefinisikan sesuatu yang TIDAK dilakukan di kelas dasar '
__init__
, dan satu-satunya kemungkinan untuk memperolehnya adalah dengan menempatkan eksekusi dalam__init__
fungsi kelas turunan' .Dengan kata lain, seseorang perlu sesuatu di kelas dasar '
__init__
selain apa yang akan secara otomatis dilakukan di kelas dasar'__init__
jika yang terakhir ini tidak diganti.BUKAN sebaliknya.
Kemudian, masalahnya adalah bahwa instruksi yang diinginkan hadir di kelas dasar '
__init__
tidak lagi diaktifkan pada saat instantiation. Untuk mengimbangi inaktivasi ini, diperlukan sesuatu yang khusus: memanggil kelas dasar secara eksplisit '__init__
, untuk MENJAGA , BUKAN TAMBAH, inisialisasi dilakukan oleh kelas-dasar'__init__
. Itulah tepatnya yang dikatakan dalam dokumen resmi:Itu saja ceritanya:
ketika tujuannya adalah untuk MENJAGA inisialisasi yang dilakukan oleh kelas-dasar, yaitu pewarisan murni, tidak ada yang istimewa diperlukan, seseorang hanya harus menghindari untuk mendefinisikan suatu
__init__
fungsi dalam kelas turunanketika tujuannya adalah untuk MENGGANTI inisialisasi yang dilakukan oleh kelas-dasar,
__init__
harus didefinisikan dalam kelas turunanketika tujuannya adalah untuk ADD proses ke inisialisasi yang dilakukan oleh kelas-dasar, kelas turunan '
__init__
harus didefinisikan, terdiri dari panggilan eksplisit ke kelas-dasar__init__
Apa yang saya rasa mencengangkan dalam jabatan Anon bukan hanya bahwa ia mengungkapkan kebalikan dari teori pewarisan, tetapi bahwa ada 5 orang yang lewat yang dipungut suara tanpa mengubah rambut, dan terlebih lagi tidak ada yang bereaksi dalam 2 tahun di utas yang subjek yang menarik harus dibaca relatif sering.
sumber
Sunting : (setelah perubahan kode)
Tidak ada cara bagi kami untuk memberi tahu Anda apakah Anda perlu atau tidak memanggil orang tua Anda
__init__
(atau fungsi lainnya). Warisan jelas akan bekerja tanpa panggilan semacam itu. Itu semua tergantung pada logika kode Anda: misalnya, jika semua Anda__init__
dilakukan di kelas induk, Anda bisa melewatkan kelas anak__init__
sama sekali.pertimbangkan contoh berikut:
sumber
Tidak ada aturan yang keras dan cepat. Dokumentasi untuk kelas harus menunjukkan apakah subclass harus memanggil metode superclass. Kadang-kadang Anda ingin sepenuhnya mengganti perilaku superclass, dan di lain waktu menambahnya - yaitu memanggil kode Anda sendiri sebelum dan / atau setelah panggilan superclass.
Pembaruan: Logika dasar yang sama berlaku untuk panggilan metode apa pun. Konstruktor kadang-kadang membutuhkan pertimbangan khusus (karena mereka sering mengatur keadaan yang menentukan perilaku) dan destruktor karena mereka paralel dengan konstruktor (misalnya dalam alokasi sumber daya, misalnya koneksi basis data). Tetapi hal yang sama mungkin berlaku, misalnya, pada
render()
metode widget.Pembaruan lebih lanjut: Apa OPP? Apakah maksud Anda OOP? Tidak - subclass sering perlu tahu sesuatu tentang desain superclass. Bukan detail implementasi internal - tetapi kontrak dasar yang dimiliki superclass dengan kliennya (menggunakan kelas). Ini tidak melanggar prinsip-prinsip OOP dengan cara apa pun. Itu sebabnya
protected
adalah konsep yang valid dalam OOP secara umum (meskipun tidak, tentu saja, dengan Python).sumber
IMO, Anda harus memanggilnya. Jika superclass
object
Anda, Anda tidak boleh, tetapi dalam kasus lain saya pikir itu luar biasa untuk tidak menyebutnya. Seperti yang sudah dijawab oleh orang lain, akan sangat nyaman jika kelas Anda bahkan tidak perlu menimpa__init__
dirinya sendiri, misalnya ketika tidak memiliki keadaan internal (tambahan) untuk diinisialisasi.sumber
Ya, Anda harus selalu memanggil kelas dasar
__init__
secara eksplisit sebagai praktik pengkodean yang baik. Lupa melakukan ini dapat menyebabkan masalah halus atau menjalankan kesalahan waktu. Ini benar bahkan jika__init__
tidak mengambil parameter apa pun. Ini tidak seperti bahasa lain di mana kompiler secara implisit akan memanggil konstruktor kelas dasar untuk Anda. Python tidak melakukan itu!Alasan utama untuk selalu memanggil kelas dasar
_init__
adalah bahwa kelas dasar biasanya dapat membuat variabel anggota dan menginisialisasi mereka ke default. Jadi jika Anda tidak memanggil kelas dasar init, tidak ada kode yang akan dieksekusi dan Anda akan berakhir dengan kelas dasar yang tidak memiliki variabel anggota.Contoh :
Ini mencetak ..
Jalankan kode ini .
sumber