de-vraag
  • Pertanyaan
  • Tag
  • Pengguna
Notifikasi
Imbalan
Registrasi
Setelah Anda mendaftar, Anda akan diberitahu tentang balasan dan komentar untuk pertanyaan Anda.
Gabung
Jika Anda sudah memiliki akun, masuk untuk memeriksa pemberitahuan baru.
Akan ada hadiah untuk pertanyaan, jawaban, dan komentar tambahan.
Lebih
Sumber
Sunting
Zero Piraeus
Zero Piraeus
Question

Mengapa Python 3.x's super() sihir?

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?

152 2013-10-26T14:58:32+00:00 1
Martijn Pieters
Martijn Pieters
Pertanyaan edit 10 April 2014 в 4:23
Pemrograman
python
python-3.x
super
Solution / Answer
Martijn Pieters
Martijn Pieters
26 Oktober 2013 в 4:41
2013-10-26T16:41:24+00:00
Lebih
Sumber
Sunting
#22628809

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 &#39;super&#39;. Dengan demikian, jika anda (secara global) ganti nama super untuk makan malam dan menggunakan makan malam tapi tidak super, 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 bernama super, 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
Martijn Pieters
Martijn Pieters
Jawaban edit 10 Februari 2018 в 6:27
210
0
Related communities 6
Python Indonesia
Python Indonesia
24 686 pengguna
Programmer Python Indonesia. Group ini dikelola oleh sejumlah admin. Baca pesan tersemat / pinned message: https://t.me/pythonID/217588
Buka telegram
Indonesian Python Warriors
Indonesian Python Warriors
1 462 pengguna
Di grup ini tidak ada kewajiban untuk menggunakan username dan foto. Yang tidak boleh adalah spamming. Gak boleh baper, kalau nanya yang bener, eror jangan difoto pake HP, gunakan screenshot, code copas ke pastebin.com lalu share link ke sini.
Buka telegram
Python-ID Jogja
Python-ID Jogja
962 pengguna
Buka telegram
BASIC PYTHON INDONESIA
BASIC PYTHON INDONESIA
214 pengguna
Buka telegram
Python Newbie Indonesia
Python Newbie Indonesia
180 pengguna
Peraturan grup Python Newbie 🌻Dilarang spam 🌻Dilarang menggunakan bahasa kasar 🌻Dilarang beriklan di grup tanpa seizin admin Beberapa video dasar python dapat diliat melalui channel youtube juan aditya Jangan lupa untuk subscribe ya🙏
Buka telegram
PythonWealth Indonesia 🇮🇩
PythonWealth Indonesia 🇮🇩
29 pengguna
Buka telegram
Tambahkan pertanyaan
Kategori
Semua
Teknologi
Budaya / Rekreasi
Kehidupan / Seni
Ilmu Pengetahuan
Profesional
Bisnis
Pengguna
Semua
Baru
Populer
1
Asilbek Qadamboyev
Terdaftar 7 jam yang lalu
2
Akshit Mehta
Terdaftar 2 hari yang lalu
3
me you
Terdaftar 6 hari yang lalu
4
Никита иванов
Terdaftar 1 minggu yang lalu
5
Alex1976G_06
Terdaftar 1 minggu yang lalu
ID
JA
KO
RO
RU
© de-vraag 2022
Sumber
stackoverflow.com
di bawah lisensi cc by-sa 3.0 dengan atribusi