Awalnya saya ingin menanyakan pertanyaan ini , tetapi kemudian saya menemukan itu sudah terpikirkan sebelumnya ...
Googling sekitar saya menemukan contoh memperluas configparser ini . Pekerjaan berikut dengan Python 3:
$ python3
Python 3.2.3rc2 (default, Mar 21 2012, 06:59:51)
[GCC 4.6.3] on linux2
>>> from configparser import SafeConfigParser
>>> class AmritaConfigParser(SafeConfigParser):
... def __init_(self):
... super().__init__()
...
>>> cfg = AmritaConfigParser()
Tetapi tidak dengan Python 2:
>>> class AmritaConfigParser(SafeConfigParser):
... def __init__(self):
... super(SafeConfigParser).init()
...
>>> cfg = AmritaConfigParser()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __init__
TypeError: must be type, not classob
Kemudian saya membaca sedikit tentang gaya Kelas Baru vs Kelas Lama Python (misalnya di sini . Dan sekarang saya bertanya-tanya, saya bisa melakukan:
class MyConfigParser(ConfigParser.ConfigParser):
def Write(self, fp):
"""override the module's original write funcition"""
....
def MyWrite(self, fp):
"""Define new function and inherit all others"""
Tapi, haruskah saya menelepon init? Apakah ini setara dengan Python 2:
class AmritaConfigParser(ConfigParser.SafeConfigParser):
#def __init__(self):
# super().__init__() # Python3 syntax, or rather, new style class syntax ...
#
# is this the equivalent of the above ?
def __init__(self):
ConfigParser.SafeConfigParser.__init__(self)
python
inheritance
configparser
Oz123
sumber
sumber
__init__()
di subkelas jika yang dilakukannya hanyalah memanggil kelas super '__init__()
(baik dalam Python 2 atau 3) - alih-alih biarkan super diwariskan.Jawaban:
super()
(tanpa argumen) diperkenalkan dengan Python 3 (bersama dengan__class__
):jadi itu akan menjadi Python 2 yang setara untuk kelas gaya baru:
untuk kelas gaya lama Anda selalu dapat menggunakan:
sumber
super(__class__)
memberiNameError: global name '__class__' is not defined
, dansuper(self.__class__)
juga salah. Anda harus memberikan contoh sebagai argumen kedua, yang menyarankan Anda perlu melakukannyasuper(self.__class__, self)
, tetapi itu salah . JikaClass2
mewarisi dariClass1
danClass1
panggilansuper(self.__class__, self).__init__()
,Class1
's__init__
maka akan menyebut dirinya ketika instantiate sebuah contoh dariClass2
.TypeError: super() takes at least 1 argument (0 given)
ketika mencoba memanggilsuper(self.__class__)
dengan Python 2. (Yang tidak masuk akal, tetapi ini menunjukkan berapa banyak informasi yang hilang dari jawaban ini.)__init__()
tanpa argumen pada objek yang super terikat (yang Anda dapatkan dengan meneleponsuper(self.__class__)
dengan hanya satu argumen), Anda memerlukan objek yang super terikat maka harus bekerja:super(CurrentClass, self).__init__()
. Jangan gunakanself.__class__
karena itu akan selalu merujuk ke kelas yang sama saat memanggil induk dan oleh karena itu buat pengulangan tak terbatas jika induk tersebut juga melakukan hal yang sama.__class__
(anggota) juga ada di Python2 .__class__
anggota tetapi tentang penutupan leksikal yang dibuat secara implisit__class__
yang selalu merujuk ke kelas yang saat ini sedang didefinisikan, yang tidak ada di python2.Dalam kasus pewarisan tunggal (saat Anda membuat subkelas satu kelas saja), kelas baru Anda mewarisi metode dari kelas dasar. Ini termasuk
__init__
. Jadi jika Anda tidak mendefinisikannya di kelas Anda, Anda akan mendapatkan satu dari basis.Hal-hal mulai menjadi rumit jika Anda memperkenalkan beberapa warisan (membuat subkelas lebih dari satu kelas dalam satu waktu). Ini karena jika lebih dari satu kelas dasar yang dimiliki
__init__
, kelas Anda hanya akan mewarisi kelas pertama.Dalam kasus seperti itu, Anda harus benar-benar menggunakan
super
jika Anda bisa, saya akan menjelaskan alasannya. Tapi tidak selalu bisa. Masalahnya adalah bahwa semua kelas dasar Anda juga harus menggunakannya (dan kelas dasarnya juga - seluruh pohon).Jika itu masalahnya, maka ini juga akan bekerja dengan benar (dengan Python 3 tetapi Anda dapat mengerjakannya ulang menjadi Python 2 - ia juga memiliki
super
):Perhatikan bagaimana kedua kelas dasar digunakan
super
meskipun mereka tidak memiliki kelas dasarnya sendiri.Apa yang
super
dilakukannya adalah: memanggil metode dari kelas berikutnya dalam MRO (urutan resolusi metode). MRO untukC
adalah:(C, A, B, object)
. Anda dapat mencetakC.__mro__
untuk melihatnya.Jadi,
C
mewarisi__init__
dariA
dansuper
dalamA.__init__
panggilanB.__init__
(B
mengikutiA
di MRO).Jadi dengan tidak melakukan apa pun
C
, Anda akhirnya memanggil keduanya, yang Anda inginkan.Sekarang jika Anda tidak menggunakan
super
, Anda akan mendapatkan warisanA.__init__
(seperti sebelumnya) tapi kali ini tidak ada yang akan memanggilB.__init__
Anda.Untuk memperbaikinya, Anda harus menentukan
C.__init__
:Masalahnya adalah bahwa di pohon MI yang lebih rumit,
__init__
metode beberapa kelas mungkin akan dipanggil lebih dari sekali sedangkan super / MRO menjamin bahwa mereka dipanggil hanya sekali.sumber
Notice how both base classes use super even though they don't have their own base classes.
Mereka punya. Dalam py3k setiap objek subclass kelas.Singkatnya, mereka setara. Mari kita lihat sejarah:
(1) pada awalnya, fungsinya terlihat seperti ini.
(2) untuk membuat kode lebih abstrak (dan lebih portabel). Metode umum untuk mendapatkan Super-Class ditemukan seperti:
Dan fungsi init dapat berupa:
Namun membutuhkan pengalihan eksplisit baik kelas dan contoh melanggar aturan DRY (Jangan Ulangi Diri Anda) sedikit.
(3) di V3. Itu lebih pintar,
dalam banyak kasus sudah cukup. Anda dapat merujuk ke http://www.python.org/dev/peps/pep-3135/
sumber
Hanya untuk mendapatkan contoh sederhana dan lengkap untuk Python 3, yang sepertinya digunakan kebanyakan orang sekarang.
memberi
sumber
Implementasi python3 lain yang melibatkan penggunaan kelas Abstrak dengan super (). Anda harus ingat itu
memiliki efek yang sama seperti
Ingat ada 'diri' yang tersembunyi di super (), Jadi objek yang sama diteruskan ke metode superclass init dan atribut ditambahkan ke objek yang memanggilnya. Karenanya
super()
akan diterjemahkan kePerson
dan kemudian jika Anda menyertakan diri yang tersembunyi, Anda mendapatkan frag kode di atas.sumber