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 supermenjadi 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 supermenjadi supperdan menggunakan suppertetapi 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 superkata 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