super()
Perilaku sulap baru ditambahkan untuk menghindari melanggar prinsip KERING (Jangan Ulangi Diri Sendiri), lihat PEP 3135 . Harus secara eksplisit memberi nama kelas dengan merujuknya sebagai global juga rentan terhadap masalah rebinding yang Anda temukan dengan super()
dirinya 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 dekorator kelas di mana dekorator mengembalikan objek baru, yang mengubah 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
super()
__class__
Sel ajaib menghindari masalah ini dengan baik dengan memberi Anda akses ke objek kelas asli.
PEP diluncurkan oleh Guido, yang awalnya membayangkan super
menjadi kata kunci , dan gagasan menggunakan sel untuk mencari kelas saat ini juga miliknya . Tentu saja, gagasan untuk menjadikannya kata kunci adalah bagian dari konsep pertama PEP .
Namun, sebenarnya Guido sendiri yang kemudian menjauh dari gagasan kata kunci sebagai 'terlalu ajaib' , malah mengusulkan penerapan saat ini. Dia mengantisipasi bahwa menggunakan nama yang berbeda untuk super()
bisa menjadi masalah :
Tambalan saya menggunakan solusi perantara: diasumsikan Anda butuhkan __class__
setiap kali Anda menggunakan variabel bernama 'super'
. Jadi, jika Anda (secara global) mengganti nama super
menjadi supper
dan menggunakan supper
tetapi tidak super
, itu tidak akan berfungsi tanpa argumen (tapi itu masih akan berfungsi jika Anda meneruskannya baik
__class__
atau objek kelas yang sebenarnya); jika Anda memiliki nama variabel yang tidak terkait super
, semuanya akan berfungsi tetapi metode ini akan menggunakan jalur panggilan yang sedikit lebih lambat yang digunakan untuk variabel sel.
Jadi, pada akhirnya, Guido sendiri yang menyatakan bahwa menggunakan super
kata kunci tidak terasa benar, dan bahwa menyediakan __class__
sel ajaib adalah kompromi yang dapat diterima.
Saya setuju bahwa keajaiban, perilaku implisit implementasi agak mengejutkan, tetapi super()
merupakan salah satu fungsi yang paling salah diterapkan dalam bahasa. Lihat saja semua kesalahan penggunaan super(type(self), self)
atau super(self.__class__, self)
doa yang ditemukan di Internet; jika ada kode yang dipanggil dari kelas turunan, Anda akan berakhir dengan pengecualian rekursi tak terbatas . Di sangat paling tidak disederhanakan super()
panggilan, tanpa argumen, menghindari itu masalah.
Adapun yang diganti namanya super_
; referensi saja __class__
dalam metode Anda juga dan itu akan bekerja lagi. Sel dibuat jika Anda merujuk salah satu super
atau __class__
nama - nama dalam metode Anda:
>>> 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