Penggunaan berikut ini super()
memunculkan TypeError: mengapa?
>>> from HTMLParser import HTMLParser
>>> class TextParser(HTMLParser):
... def __init__(self):
... super(TextParser, self).__init__()
... self.all_data = []
...
>>> TextParser()
(...)
TypeError: must be type, not classobj
Ada pertanyaan serupa di StackOverflow: Python super () memunculkan TypeError , di mana kesalahannya dijelaskan oleh fakta bahwa kelas pengguna bukan kelas gaya baru. Namun, kelas di atas adalah kelas gaya baru, karena mewarisi dari object
:
>>> isinstance(HTMLParser(), object)
True
Apa yang saya lewatkan? Bagaimana saya bisa menggunakan super()
, di sini?
Menggunakan HTMLParser.__init__(self)
bukannya super(TextParser, self).__init__()
akan bekerja, tapi saya ingin memahami TypeError.
PS: Joachim menunjukkan bahwa menjadi contoh kelas gaya baru tidak setara dengan menjadi object
. Saya membaca kebalikannya berkali-kali, karenanya kebingungan saya (contoh uji contoh kelas gaya baru berdasarkan object
uji contoh: https://stackoverflow.com/revisions/2655651/3 ).
sumber
super.__doc__
tidak menyebutkan apa pun tentang gaya lama vs baru!super()
hanya berfungsi untuk kelas gaya baru (dan objek) disebutkan dalam dokumen HTML ( docs.python.org/library/functions.html#super ).Jawaban:
Baiklah, itu biasa "
super()
tidak dapat digunakan dengan kelas gaya lama".Namun, poin penting adalah bahwa tes yang benar untuk "apakah ini contoh gaya baru (yaitu objek)?" adalah
dan tidak (seperti dalam pertanyaan):
Untuk kelas , tes "apakah ini kelas gaya baru" yang benar adalah:
The titik penting adalah bahwa dengan kelas gaya lama, yang kelas dari sebuah contoh dan yang jenis yang berbeda. Berikut,
OldStyle().__class__
adalahOldStyle
, yang tidak mewarisi dariobject
, sedangkantype(OldStyle())
adalahinstance
jenis, yang tidak mewarisi dariobject
. Pada dasarnya, kelas gaya lama hanya menciptakan objek bertipeinstance
(sedangkan kelas gaya baru menciptakan objek yang tipenya adalah kelas itu sendiri). Ini mungkin mengapa turunannyaOldStyle()
adalahobject
: iatype()
mewarisi dariobject
(fakta bahwa kelasnya tidak diwarisi dariobject
tidak masuk hitungan: kelas gaya lama hanya membangun objek tipe baruinstance
). Referensi parsial:https://stackoverflow.com/a/9699961/42973 .PS: Perbedaan antara kelas gaya baru dan kelas gaya lama juga dapat dilihat dengan:
(kelas gaya lama bukan tipe, jadi mereka tidak bisa menjadi tipe instance mereka).
sumber
(Oldstyle().__class__ is Oldstyle)
adalahTrue
OldStyle().__class__
adalah untuk menunjukkan bagaimana menguji apakah suatu objek (OldStyle()
) berasal dari kelas gaya lama. Dengan hanya kelas gaya baru dalam pikiran, orang mungkin tergoda untuk melakukan tes denganisinstance(OldStyle(), object)
gantinya.object
, sehingga mengacaukan Anda dengan proxy.super () dapat digunakan hanya di kelas-kelas gaya baru, yang berarti kelas root perlu mewarisi dari kelas 'objek'.
Sebagai contoh, kelas atas harus seperti ini:
tidak
Jadi, solusinya adalah memanggil metode init orang tua secara langsung, seperti ini:
sumber
self
parameter yangHTMLParser.__init__()
dipanggil.Anda juga bisa menggunakan
class TextParser(HTMLParser, object):
. Hal ini membuatTextParser
sebuah gaya baru kelas, dansuper()
dapat digunakan.sumber
Masalahnya adalah yang
super
membutuhkanobject
sebagai leluhur:Pada pemeriksaan lebih dekat seseorang menemukan:
Tapi:
Jadi solusi untuk masalah Anda adalah dengan mewarisi dari objek maupun dari HTMLParser. Tapi pastikan objek menjadi yang terakhir di kelas MRO:
sumber
type(myclass)
, yang penting adalah apakahmyclass
mewarisi dari objek (yaitu apakahisinstance(myclass, object)
itu benar — itu salah).Jika Anda melihat pohon warisan (dalam versi 2.6),
HTMLParser
mewarisi dariSGMLParser
mana warisan dariParserBase
mana tidak mewarisi dariobject
. Yaitu HTMLParser adalah kelas gaya lama.Tentang pemeriksaan Anda dengan
isinstance
, saya melakukan tes cepat di ipython:Bahkan jika suatu kelas adalah kelas gaya lama, itu masih merupakan contoh
object
.sumber
isinstance(A(), object)
, bukanisinstance(A, object)
, bukan? Dengan yang terakhir, Anda menguji apakah kelasA
adalahobject
, sedangkan pertanyaannya adalah apakah contoh dariA
seorangobject
, kan?issubclass(HTMLParser, object)
, yang mengembalikan False.cara yang benar untuk dilakukan adalah mengikuti kelas-kelas gaya lama yang tidak mewarisi dari 'objek'
sumber
A
yang menyimpan keadaan.FWIW dan meskipun saya bukan guru Python saya berhasil dengan ini
Baru saja saya mendapatkan hasil parse kembali sesuai kebutuhan.
sumber