Di Python 3.x, super()
dapat dipanggil tanpa argumen:
class A(object):
def x(self):
print("Hey now")
class B(A):
def x(self):
super().x()
>>> B().x()
Hey now
Dalam rangka untuk membuat pekerjaan ini, beberapa waktu kompilasi sihir dilakukan, salah satu konsekuensi dari ini adalah bahwa kode berikut (yang rebinds super
untuk super_
) gagal:
super_ = super
class A(object):
def x(self):
print("No flipping")
class B(A):
def x(self):
super_().x()
>>> B().x()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in x
RuntimeError: super(): __class__ cell not found
Mengapa super()
mampu menyelesaikan superclass pada saat runtime tanpa bantuan dari compiler? Adalah tidak praktis situasi di mana perilaku ini, atau alasan yang mendasari hal itu, bisa menggigit waspada programmer?
... dan, sebagai sisi pertanyaan: apakah ada contoh-contoh lain di Python fungsi, metode dll. yang dapat rusak oleh rebinding mereka dengan nama yang berbeda?
Baru magic super()
perilaku yang ditambahkan untuk menghindari melanggar D. R. Y. (Don't Repeat Yourself) prinsip, lihat PEP 3135. Harus secara eksplisit nama kelas dengan referensi itu sebagai global juga cenderung sama rebinding masalah yang anda temukan dengan super()
itu sendiri:
class Foo(Bar):
def baz(self):
return super(Foo, self).baz() + 42
Spam = Foo
Foo = something_else()
Spam().baz() # liable to blow up
Hal yang sama berlaku untuk menggunakan kelas dekorator mana dekorator kembali objek baru, yang rebinds nama kelas:
@class_decorator_returning_new_class
class Foo(Bar):
def baz(self):
# Now `Foo` is a *different class*
return super(Foo, self).baz() + 42
Ajaib super()
__kelas__
sel sidesteps masalah ini baik dengan memberikan anda akses ke kelas yang asli objek.
PEP menggebrak oleh Guido, yang awalnya dibayangkan super
menjadi sebuah kata kunci](https://mail.python.org/pipermail/python-3000/2007-April/006667.html), dan ide untuk menggunakan ponsel untuk mencari kelas saat ini juga. Tentu saja, ide untuk membuat sebuah kata kunci adalah bagian dari draft pertama dari PEP.
Namun, itu sebenarnya Guido sendiri yang kemudian melangkah menjauh dari kata kunci ide sebagai 'terlalu ajaib', mengusulkan penerapan ini sebagai gantinya. Dia diantisipasi bahwa dengan menggunakan nama yang berbeda untuk super()
bisa menjadi masalah:
Saya patch menggunakan perantara solusi: ini mengasumsikan anda perlu
__kelas__
setiap kali anda menggunakan sebuah variabel bernama'super'
. Dengan demikian, jika anda (secara global) ganti namasuper
untukmakan malam
dan menggunakanmakan malam
tapi tidaksuper
, itu tidak't bekerja tanpa argumen (tapi itu masih akan bekerja jika anda lulus baik__kelas__
atau kelas sebenarnya objek); jika anda memiliki aplikasi yang tidak terkait variabel bernamasuper
, hal-hal akan bekerja tetapi metode yang akan digunakan sedikit lebih lambat call jalan yang digunakan untuk sel variabel.
Jadi, pada akhirnya, itu adalah Guido dirinya yang menyatakan bahwa dengan menggunakan super
kata kunci tidak merasa benar, dan yang menyediakan magic __kelas__
sel adalah kompromi yang dapat diterima.
Saya setuju bahwa sihir, implisit perilaku implementasi agak mengejutkan, tapi super()
adalah salah satu yang paling mis diterapkan fungsi-fungsi dalam bahasa. Hanya mengambil melihat semua disalahgunakan super(jenis(self), diri)
atau super(self.__hotel__, mandiri)
doa yang ditemukan di Internet, jika ada kode yang pernah disebut dari kelas yang diturunkan anda'd end up dengan rekursi tak terbatas exception. Setidaknya modern super()
panggilan, tanpa argumen, menghindari yang masalah.
Adapun berganti nama menjadi super_
; hanya referensi __kelas__
dalam metode anda juga dan'll bekerja lagi. Sel ini dibuat jika anda referensi baik super
atau __kelas__
nama metode:
>>> super_ = super
>>> class A(object):
... def x(self):
... print("No flipping")
...
>>> class B(A):
... def x(self):
... __class__ # just referencing it is enough
... super_().x()
...
>>> B().x()
No flipping