Saat membuat hierarki objek sederhana dalam Python, saya ingin dapat memanggil metode dari kelas induk dari kelas turunan. Di Perl dan Java, ada kata kunci untuk ini ( super
). Di Perl, saya mungkin melakukan ini:
package Foo;
sub frotz {
return "Bamf";
}
package Bar;
@ISA = qw(Foo);
sub frotz {
my $str = SUPER::frotz();
return uc($str);
}
Dalam Python, tampaknya saya harus memberi nama kelas induk secara eksplisit dari anak. Pada contoh di atas, saya harus melakukan sesuatu seperti Foo::frotz()
.
Ini sepertinya tidak benar karena perilaku ini menyulitkan untuk membuat hierarki yang mendalam. Jika anak-anak perlu tahu kelas apa yang mendefinisikan metode yang diwariskan, maka semua jenis rasa sakit informasi dibuat.
Apakah ini keterbatasan sebenarnya dalam python, celah dalam pemahaman saya atau keduanya?
python
inheritance
class
object
John
sumber
sumber
Jawaban:
Ya, tetapi hanya dengan kelas gaya baru . Gunakan
super()
fungsinya:Untuk python <3, gunakan:
sumber
super(Foo, self)
untuk Python 2.x benar? Dalam Python 3.x,super()
lebih disukai benar?Python juga memiliki super juga:
super(type[, object-or-type])
Contoh:
sumber
akan baik-baik saja, apakah kelas induk langsung didefinisikan
frotz
sendiri atau diwarisi.super
hanya diperlukan untuk dukungan yang tepat dari multiple inheritance (dan kemudian hanya berfungsi jika setiap kelas menggunakannya dengan benar). Secara umum,AnyClass.whatever
akan mencariwhatever
diAnyClass
leluhur 's jikaAnyClass
tidak mendefinisikan / menimpa itu, dan ini berlaku untuk 'kelas anak memanggil metode orangtua' seperti untuk terjadinya lainnya!sumber
parent
, itu berada dalam lingkup seluruh kelas, bukan?Python 3 memiliki sintaks yang berbeda dan lebih sederhana untuk memanggil metode induk.
Jika
Foo
kelas mewarisi dariBar
, maka dariBar.__init__
dapat dipanggilFoo
melaluisuper().__init__()
:sumber
Banyak jawaban telah menjelaskan cara memanggil metode dari orang tua yang telah ditimpa pada anak.
Namun
bisa juga berarti:
Anda dapat memanggil metode yang diwarisi dari kelas induk sama seperti jika mereka adalah metode kelas anak, asalkan mereka belum ditimpa.
misalnya dalam python 3:
ya, ini mungkin cukup jelas, tetapi saya merasa bahwa tanpa menunjukkan ini orang dapat meninggalkan utas ini dengan kesan Anda harus melompat melalui lingkaran konyol hanya untuk mengakses metode yang diwariskan dalam python. Terutama karena pertanyaan ini sangat dicari dalam "cara mengakses metode kelas induk dengan Python", dan OP ditulis dari sudut pandang seseorang yang baru mengenal python.
Saya menemukan: https://docs.python.org/3/tutorial/classes.html#inheritance berguna dalam memahami bagaimana Anda mengakses metode yang diwariskan.
sumber
self.string
tidak akan melakukan apa pun. Namun di kelas C Anda masih bisa meneleponB().bar(string)
Berikut adalah contoh penggunaan super () :
sumber
Ada super () di Python juga. Ini agak miring, karena kelas gaya lama dan baru Python, tetapi cukup umum digunakan misalnya dalam konstruktor:
sumber
Saya akan merekomendasikan menggunakan
CLASS.__bases__
sesuatu seperti inisumber
Jika Anda tidak tahu berapa banyak argumen yang mungkin Anda dapatkan, dan ingin menyampaikan semuanya kepada anak juga:
(Dari: Python - Cara terbersih untuk mengganti __init__ di mana kwarg opsional harus digunakan setelah panggilan super ()? )
sumber
Ada super () di python juga.
Contoh untuk bagaimana metode kelas super dipanggil dari metode kelas bawah
Contoh ini mirip dengan yang dijelaskan di atas. Namun ada satu perbedaan yang super tidak memiliki argumen yang dilewatinya. Kode di atas ini dapat dieksekusi dalam versi python 3.4.
sumber
Dalam contoh ini
cafec_param
adalah kelas dasar (kelas induk) danabc
merupakan kelas anak.abc
memanggilAWC
metode di kelas dasar.Keluaran
sumber
Dalam Python 2, saya tidak memiliki banyak keberuntungan dengan super (). Saya menggunakan jawaban dari jimifiki pada utas SO ini bagaimana merujuk ke metode induk dengan python?. Kemudian, saya menambahkan sedikit twist saya sendiri untuk itu, yang saya pikir merupakan peningkatan dalam kegunaan (Terutama jika Anda memiliki nama kelas yang panjang).
Tentukan kelas dasar dalam satu modul:
Kemudian impor kelas ke modul lain
as parent
:sumber
class A(object):
alih-alihclass A():
Then super () akan bekerjasumber
sumber
Ini adalah metode yang lebih abstrak:
sumber
super(self.__class__, self).baz(arg)
.