public interface IInterface
{
void show();
}
public class MyClass : IInterface
{
#region IInterface Members
public void show()
{
Console.WriteLine("Hello World!");
}
#endregion
}
Bagaimana cara saya menerapkan Python yang setara dengan kode C # ini?
class IInterface(object):
def __init__(self):
pass
def show(self):
raise Exception("NotImplementedException")
class MyClass(IInterface):
def __init__(self):
IInterface.__init__(self)
def show(self):
print 'Hello World!'
Apakah ini ide yang bagus ?? Tolong beri contoh dalam jawaban Anda.
raise NotImplementedError
adalah apa yangshow
seharusnya tubuh - tidak masuk akal untuk meningkatkan generik sepenuhnyaException
ketika Python mendefinisikan built-in yang sangat spesifik! -)Jawaban:
Seperti yang disebutkan oleh yang lain di sini:
Antarmuka tidak diperlukan dalam Python. Ini karena Python memiliki banyak pewarisan yang tepat, dan juga ducktyping, yang berarti tempat di mana Anda harus memiliki antarmuka di Jawa, Anda tidak harus memilikinya di Python.
Yang mengatakan, masih ada beberapa kegunaan untuk antarmuka. Beberapa dari mereka dilindungi oleh Pythons Abstract Base Classes, diperkenalkan dengan Python 2.6. Mereka berguna, jika Anda ingin membuat kelas dasar yang tidak dapat dipakai, tetapi menyediakan antarmuka khusus atau bagian dari suatu implementasi.
Penggunaan lain adalah jika Anda entah bagaimana ingin menentukan bahwa suatu objek mengimplementasikan antarmuka tertentu, dan Anda dapat menggunakan ABC untuk itu juga dengan mensubklasifikasikan dari mereka. Cara lain adalah zope.interface, sebuah modul yang merupakan bagian dari Arsitektur Komponen Zope, kerangka kerja komponen yang benar-benar keren. Di sini Anda tidak membuat subkelas dari antarmuka, melainkan menandai kelas (atau bahkan instance) sebagai mengimplementasikan antarmuka. Ini juga dapat digunakan untuk mencari komponen dari komponen registri. Sangat keren!
sumber
Menggunakan modul abc untuk kelas dasar abstrak tampaknya melakukan trik.
sumber
if not server.version() == '1.0': raise ...
? Saya tidak benar-benar mendapatkan garis ini. Sebuah penjelasan akan disambut.antarmuka mendukung Python 2.7 dan Python 3.4+.
Untuk menginstal antarmuka Anda harus
Kode Contoh:
sumber
Menerapkan antarmuka dengan kelas dasar abstrak jauh lebih sederhana di Python modern 3 dan mereka melayani tujuan sebagai kontrak antarmuka untuk ekstensi plug-in.
Buat antarmuka / kelas dasar abstrak:
Buat subkelas normal dan timpa semua metode abstrak:
Anda dapat secara opsional memiliki implementasi umum dalam metode abstrak seperti pada
create_sale_invoice()
, memanggilnyasuper()
secara eksplisit dalam subkelas seperti di atas.Instansiasi dari subkelas yang tidak menerapkan semua metode abstrak gagal:
Anda juga dapat memiliki properti abstrak, metode statis, dan kelas dengan menggabungkan anotasi yang sesuai dengannya
@abstractmethod
.Kelas dasar abstrak sangat bagus untuk menerapkan sistem berbasis plugin. Semua subclass yang diimpor dari suatu kelas dapat diakses melalui
__subclasses__()
, jadi jika Anda memuat semua kelas dari direktori plugin denganimportlib.import_module()
dan jika mereka mensubclass kelas dasar, Anda memiliki akses langsung ke mereka melalui__subclasses__()
dan Anda dapat yakin bahwa kontrak antarmuka diberlakukan untuk semua mereka selama instantiasi.Berikut implementasi plugin loading untuk
AccountingSystem
contoh di atas:Kemudian Anda dapat mengakses objek plugin sistem akuntansi melalui
AccountingSystem
kelas:(Terinspirasi oleh pos PyMOTW-3 ini .)
sumber
Ada implementasi pihak ketiga dari antarmuka untuk Python (paling populer adalah Zope's , juga digunakan dalam Twisted ), tetapi lebih umum coders Python lebih suka menggunakan konsep yang lebih kaya yang dikenal sebagai "Abstrak Base Class" (ABC), yang menggabungkan antarmuka dengan kemungkinan memiliki beberapa aspek implementasi di sana juga. ABC sangat didukung dengan Python 2.6 dan yang lebih baru, lihat PEP , tetapi bahkan dalam versi Python sebelumnya mereka biasanya dilihat sebagai "cara untuk pergi" - cukup mendefinisikan kelas beberapa metode yang dinaikkan
NotImplementedError
sehingga subclass akan menjadi dengan pemberitahuan bahwa mereka sebaiknya mengganti metode itu! -)sumber
Sesuatu seperti ini (mungkin tidak berfungsi karena saya tidak memiliki Python):
sumber
__init__(self)
terhadap konstruktor?abc.ABC
jauh lebih baik daripada menaikkanNotImplementedError
- instantiation dariabc.ABC
subclass yang tidak mengimplementasikan semua metode abstrak gagal lebih awal, sehingga Anda terlindungi dari kesalahan. Lihat jawaban saya di bawah untuk melihat bagaimana kesalahannya.Pemahaman saya adalah bahwa antarmuka tidak diperlukan dalam bahasa dinamis seperti Python. Dalam Java (atau C ++ dengan kelas dasar abstraknya) antarmuka adalah cara untuk memastikan bahwa misalnya Anda melewati parameter yang tepat, dapat melakukan serangkaian tugas.
Misalnya jika Anda memiliki pengamat dan dapat diamati, diamati tertarik untuk berlangganan objek yang mendukung antarmuka IObserver, yang pada gilirannya memiliki
notify
tindakan. Ini diperiksa pada waktu kompilasi.Dalam Python, tidak ada yang namanya
compile time
dan metode pencarian dilakukan saat runtime. Selain itu, orang dapat mengganti pencarian dengan __getattr __ () atau __getattribute __ () metode ajaib. Dengan kata lain, Anda dapat mengirimkan, sebagai pengamat, objek apa pun yang dapat mengembalikan panggilan padanotify
atribut akses .Ini membawa saya pada kesimpulan, bahwa antarmuka dalam Python memang ada - hanya saja penegakannya ditunda hingga saat mereka benar-benar digunakan
sumber