Di Jawa, misalnya, @Override
anotasi tidak hanya menyediakan pemeriksaan waktu kompilasi atas penggantian, tetapi juga membuat kode dokumentasi mandiri yang sangat baik.
Saya hanya mencari dokumentasi (walaupun jika ini merupakan indikator bagi beberapa pemeriksa seperti pylint, itu bonus). Saya dapat menambahkan komentar atau docstring di suatu tempat, tetapi apa cara idiomatis untuk menunjukkan override dalam Python?
Jawaban:
Berdasarkan ini dan jawaban fwc: s saya membuat paket yang dapat diinstal pip https://github.com/mkorpela/overrides
Dari waktu ke waktu saya berakhir di sini melihat pertanyaan ini. Terutama ini terjadi setelah (lagi) melihat bug yang sama di basis kode kami: Seseorang telah melupakan beberapa "antarmuka" mengimplementasikan kelas saat mengganti nama metode di "antarmuka" ..
Nah Python bukan Java tetapi Python memiliki kekuatan - dan eksplisit lebih baik daripada implisit - dan ada kasus nyata nyata di dunia nyata di mana hal ini akan membantu saya.
Jadi di sini adalah sketsa dekorator override. Ini akan memeriksa bahwa kelas yang diberikan sebagai parameter memiliki nama metode (atau sesuatu) yang sama dengan metode yang sedang didekorasi.
Jika Anda dapat memikirkan solusi yang lebih baik, silakan posting di sini!
Ia bekerja sebagai berikut:
dan jika Anda melakukan versi yang salah itu akan menimbulkan kesalahan pernyataan selama pemuatan kelas:
sumber
overrides
dapat menyalin dokumentasi metode overridden jika metode overriding tidak memiliki metode sendiri.Berikut ini adalah implementasi yang tidak memerlukan spesifikasi nama interface_class.
sumber
Jika Anda menginginkan ini hanya untuk keperluan dokumentasi, Anda dapat menentukan dekorator override Anda sendiri:
Ini benar-benar tidak lain adalah eye-candy, kecuali jika Anda membuat override (f) sedemikian rupa yang sebenarnya memeriksa override.
Tapi kemudian, ini Python, mengapa menulisnya seperti Java?
sumber
override
dekorator.Python bukan Java. Tentu saja tidak ada yang benar-benar memeriksa waktu kompilasi.
Saya pikir komentar di docstring banyak. Ini memungkinkan setiap pengguna metode Anda untuk mengetik
help(obj.method)
dan melihat bahwa metode tersebut merupakan override.Anda juga dapat memperluas antarmuka secara eksplisit
class Foo(Interface)
, yang akan memungkinkan pengguna mengetikhelp(Interface.method)
untuk mendapatkan ide tentang fungsionalitas yang dimaksudkan metode Anda.sumber
@Override
di Jawa bukan untuk mendokumentasikan - itu untuk menangkap kesalahan ketika Anda bermaksud mengganti metode, tetapi akhirnya mendefinisikan yang baru (misalnya karena Anda salah mengeja nama; di Jawa, itu mungkin juga terjadi karena Anda menggunakan tanda tangan yang salah, tapi ini bukan masalah dengan Python - tetapi kesalahan ejaan masih).@Override
adalah dokumentasi selain kompilasi pengecekan waktu.Berimprovisasi pada @ mkorpela jawaban yang bagus , berikut adalah versi dengan
pemeriksaan yang lebih tepat, penamaan, dan mengangkat objek Kesalahan
Berikut ini tampilannya dalam praktiknya:
NotImplementedError
" tidak diterapkan di kelas dasar "menghasilkan
NotImplementedError
kesalahan yang lebih deskriptiftumpukan penuh
NotImplementedError
" tipe yang diimplementasikan yang diharapkan "menghasilkan
NotImplementedError
kesalahan yang lebih deskriptiftumpukan penuh
Hebatnya tentang jawaban @ mkorpela adalah cek terjadi selama beberapa tahap inisialisasi. Cek tidak perlu "dijalankan". Mengacu pada contoh sebelumnya,
class B
tidak pernah diinisialisasi (B()
) namunNotImplementedError
masih akan meningkat. Ini berartioverrides
kesalahan ditangkap lebih cepat.sumber
overrides.py
. Saya tidak yakin apa lagi yang dapat saya tingkatkan secara signifikan kecuali untuk mengubah jenis pengecualian dariTypeError
menjadiNotImplementedError
.types.MethodType
. Itu ide yang bagus dalam jawaban Anda.Seperti orang lain katakan tidak seperti Java tidak ada tag @Overide namun di atas Anda dapat membuat dekorator Anda sendiri tetapi saya sarankan menggunakan metode getattrib () global daripada menggunakan dict internal sehingga Anda mendapatkan sesuatu seperti berikut:
Jika Anda ingin, Anda bisa menangkap getattr () di tangkapan Anda sendiri, coba naikkan kesalahan Anda sendiri, tetapi saya pikir metode getattr lebih baik dalam kasus ini.
Ini juga menangkap semua item yang terikat ke kelas termasuk metode kelas dan vairables
sumber
Berdasarkan jawaban luar biasa @ mkorpela, saya telah menulis paket serupa ( ipromise pypi github ) yang melakukan lebih banyak pemeriksaan:
Misalkan
A
mewarisi dariB
danC
,B
mewarisi dariC
.Modul ipromise memeriksa bahwa:
Jika
A.f
menggantiB.f
,B.f
harus ada, danA
harus mewarisi dariB
. (Ini adalah cek dari paket override).Anda tidak memiliki pola yang
A.f
menyatakan bahwa itu menimpaB.f
, yang kemudian menyatakan bahwa ia menimpaC.f
.A
harus mengatakan bahwa itu menimpaC.f
karenaB
mungkin memutuskan untuk berhenti mengganti metode ini, dan itu tidak akan menghasilkan pembaruan hilir.Anda tidak memiliki pola yang
A.f
menyatakan bahwa itu menimpaC.f
, tetapiB.f
tidak menyatakan penimpaannya.Anda tidak memiliki pola
A.f
menyatakan bahwa itu menimpaC.f
, tetapiB.f
menyatakan bahwa itu menimpa dari beberapaD.f
.Ini juga memiliki berbagai fitur untuk menandai dan memeriksa penerapan metode abstrak.
sumber
Dengar paling sederhana dan bekerja di bawah Jython dengan kelas Java:
sumber
Tidak hanya dekorator yang saya buat memeriksa apakah nama atribut utama dalam adalah superclass dari kelas atribut dalam tanpa harus menentukan superclass, dekorator ini juga memeriksa untuk memastikan atribut utama harus sama dengan yang ditimpa. atribut. Metode Kelas diperlakukan seperti metode dan Metode Statis diperlakukan seperti fungsi. Dekorator ini berfungsi untuk callable, metode kelas, metode statis, dan properti.
Untuk kode sumber lihat: https://github.com/fireuser909/override
Dekorator ini hanya berfungsi untuk kelas yang merupakan instance dari override.OverridesMeta tetapi jika kelas Anda adalah instance dari metaclass khusus, gunakan fungsi create_custom_overrides_meta untuk membuat metaclass yang kompatibel dengan dekorator override. Untuk tes, jalankan modul override .__ init__.
sumber
Dalam Python 2.6+ dan Python 3.2+ Anda dapat melakukannya ( Sebenarnya mensimulasikannya , Python tidak mendukung fungsi overloading dan kelas anak secara otomatis menimpa metode induk). Kita dapat menggunakan Dekorator untuk ini. Tetapi pertama-tama, perhatikan bahwa Python
@decorators
dan Java@Annotations
adalah hal yang sama sekali berbeda. Yang sebelumnya adalah pembungkus dengan kode konkret sementara yang lain adalah flag ke compiler.Untuk ini, pertama lakukan
pip install multipledispatch
keluaran:
Satu hal yang perlu diingat adalah bahwa karena Python tidak memiliki fungsi overloading secara langsung, jadi meskipun Kelas B tidak mewarisi dari Kelas A tetapi membutuhkan semua
foo
itu selain Anda juga perlu menggunakan @Override (meskipun menggunakan alias 'Kelebihan' akan terlihat lebih baik dalam hal itu)sumber