Python中定义和使用抽象类
提起Java的抽象类大家都比较熟悉,Python中我们可以使用abc模块来构建抽象类,这里就为大家讲解在Python中定义和使用抽象类的方法
像java一样python也可以定义一个抽象类。
在讲抽象类之前,先说下抽象方法的实现。
抽象方法是基类中定义的方法,但却没有任何实现。在java中,可以把方法申明成一个接口。而在python中实现一个抽象方法的简单的方法是:
class Sheep(object): def get_size(self): raise NotImplementedError
任何从Sheep继承下来的子类必须实现get_size方法。否则就会产生一个错误。但这种实现方法有个缺点。定义的子类只有调用那个方法时才会抛错。这里有个简单方法可以在类被实例化后触发它。使用python提供的abc模块。
import abc class Sheep(object): __metaclass__ = abc.ABCMeta @abc.absractmethod def get_size(self): return
这里实例化Sheep类或任意从其继承的子类(未实现get_size)时候都会抛出异常。
因此,通过定义抽象类,可以定义子类的共同method(强制其实现)。
如何使用抽象类
import abc class A(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def load(self, input): return @abc.abstractmethod def save(self, output, data): return
通过ABCMeta元类来创建一个抽象类, 使用abstractmethod装饰器来表明抽象方法
注册具体类
class B(object): def load(self, input): return input.read() def save(self, output, data): return output.write(data) A.register(B) if __name__ == '__main__': print issubclass(B, A) # print True print isinstance(B(), A) # print True
从抽象类注册一个具体的类
子类化实现
class C(A): def load(self, input): return input.read() def save(self, output, data): return output.write(data) if __name__ == '__main__': print issubclass(C, A) # print True print isinstance(C(), A) # print True
可以使用继承抽象类的方法来实现具体类这样可以避免使用register. 但是副作用是可以通过基类找出所有的具体类
for sc in A.__subclasses__(): print sc.__name__ # print C
如果使用继承的方式会找出所有的具体类,如果使用register的方式则不会被找出
使用__subclasshook__
使用__subclasshook__后只要具体类定义了与抽象类相同的方法就认为是他的子类
import abc class A(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def say(self): return 'say yeah' @classmethod def __subclasshook__(cls, C): if cls is A: if any("say" in B.__dict__ for B in C.__mro__): return True return NotTmplementd class B(object): def say(self): return 'hello' print issubclass(B, A) # True print isinstance(B(), A) # True print B.__dict__ # {'say': <function say at 0x7f...>, ...} print A.__subclasshook__(B) # True
不完整的实现
class D(A): def save(self, output, data): return output.write(data) if __name__ == '__main__': print issubclass(D, A) # print True print isinstance(D(), A) # raise TypeError
如果构建不完整的具体类会抛出D不能实例化抽象类和抽象方法
具体类中使用抽象基类
import abc from cStringIO import StringIO class A(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def retrieve_values(self, input): pirnt 'base class reading data' return input.read() class B(A): def retrieve_values(self, input): base_data = super(B, self).retrieve_values(input) print 'subclass sorting data' response = sorted(base_data.splitlines()) return response input = StringIO("""line one line two line three """) reader = B() print reader.retrieve_values(input)
打印结果
base class reading data subclass sorting data ['line one', 'line two', 'line three']
可以使用super来重用抽象基类中的罗辑, 但会迫使子类提供覆盖方法.
抽象属性
import abc class A(object): __metaclass__ = abc.ABCMeta @abc.abstractproperty def value(self): return 'should never get here.' class B(A): @property def value(self): return 'concrete property.' try: a = A() print 'A.value', a.value except Exception, err: print 'Error: ', str(err) b = B() print 'B.value', b.value
打印结果,A不能被实例化,因为只有一个抽象的property getter method.
Error: ... print concrete property
定义抽象的读写属性
import abc class A(object): __metaclass__ = abc.ABCMeta def value_getter(self): return 'Should never see this.' def value_setter(self, value): return value = abc.abstractproperty(value_getter, value_setter) class B(A): @abc.abstractproperty def value(self): return 'read-only' class C(A): _value = 'default value' def value_getter(self): return self._value def value_setter(self, value): self._value = value value = property(value_getter, value_setter) try: a = A() print a.value except Exception, err: print str(err) try: b = B() print b.value except Exception, err: print str(err) c = C() print c.value c.value = 'hello' print c.value
打印结果, 定义具体类的property时必须与抽象的abstract property相同。如果只覆盖其中一个将不会工作.
error: ... error: ... print 'default value' print 'hello'
使用装饰器语法来实现读写的抽象属性, 读和写的方法应该相同.
import abc class A(object): __metaclass__ = abc.ABCMeta @abc.abstractproperty def value(self): return 'should never see this.' @value.setter def value(self, _value): return class B(A): _value = 'default' @property def value(self): return self._value @value.setter def value(self, _value): self._value = _value b = B() print b.value # print 'default' b.value = 'hello' print b.value # print 'hello'
更多Python中定义和使用抽象类相关文章请关注PHP中文网!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Halaman H5 perlu dikekalkan secara berterusan, kerana faktor -faktor seperti kelemahan kod, keserasian pelayar, pengoptimuman prestasi, kemas kini keselamatan dan peningkatan pengalaman pengguna. Kaedah penyelenggaraan yang berkesan termasuk mewujudkan sistem ujian lengkap, menggunakan alat kawalan versi, kerap memantau prestasi halaman, mengumpul maklum balas pengguna dan merumuskan pelan penyelenggaraan.

PS "Memuatkan" Masalah disebabkan oleh akses sumber atau masalah pemprosesan: Kelajuan bacaan cakera keras adalah perlahan atau buruk: Gunakan CrystaldiskInfo untuk memeriksa kesihatan cakera keras dan menggantikan cakera keras yang bermasalah. Memori yang tidak mencukupi: Meningkatkan memori untuk memenuhi keperluan PS untuk imej resolusi tinggi dan pemprosesan lapisan kompleks. Pemandu kad grafik sudah lapuk atau rosak: Kemas kini pemandu untuk mengoptimumkan komunikasi antara PS dan kad grafik. Laluan fail terlalu panjang atau nama fail mempunyai aksara khas: Gunakan laluan pendek dan elakkan aksara khas. Masalah PS sendiri: Pasang semula atau membaiki pemasang PS.

Bagaimana untuk mendapatkan data dinamik 58.com halaman kerja semasa merangkak? Semasa merangkak halaman kerja 58.com menggunakan alat crawler, anda mungkin menghadapi ...

Penjelasan terperinci mengenai kemahiran kod JavaScript semasa menulis kod JavaScript, kita sering menemui garis kod yang terlalu panjang, yang bukan sahaja mempengaruhi kebolehbacaan kod ...

PS yang tersangkut pada "memuatkan" apabila boot boleh disebabkan oleh pelbagai sebab: Lumpuhkan plugin yang korup atau bercanggah. Padam atau namakan semula fail konfigurasi yang rosak. Tutup program yang tidak perlu atau menaik taraf memori untuk mengelakkan memori yang tidak mencukupi. Naik taraf ke pemacu keadaan pepejal untuk mempercepatkan bacaan cakera keras. Pasang semula PS untuk membaiki fail sistem rasuah atau isu pakej pemasangan. Lihat maklumat ralat semasa proses permulaan analisis log ralat.

Menyelesaikan masalah Permulaan Photoshop Perlahan memerlukan pendekatan berbilang arah, termasuk: menaik taraf perkakasan (memori, pemacu keadaan pepejal, CPU); menyahpasang pemalam yang sudah lapuk atau tidak serasi; membersihkan sampah sistem dan program latar belakang yang berlebihan dengan kerap; menutup program yang tidak relevan dengan berhati -hati; Mengelakkan membuka sejumlah besar fail semasa permulaan.

Alasan pemuatan PS yang perlahan adalah kesan gabungan perkakasan (CPU, memori, cakera keras, kad grafik) dan perisian (sistem, program latar belakang). Penyelesaian termasuk: Menaik taraf perkakasan (terutamanya menggantikan pemacu keadaan pepejal), mengoptimumkan perisian (membersihkan sampah sistem, mengemas kini pemacu, menyemak tetapan PS), dan memproses fail PS. Penyelenggaraan komputer yang kerap juga boleh membantu meningkatkan kelajuan berjalan PS.

"Memuatkan" gagap berlaku apabila membuka fail pada PS. Sebab-sebabnya mungkin termasuk: fail yang terlalu besar atau rosak, memori yang tidak mencukupi, kelajuan cakera keras perlahan, masalah pemacu kad grafik, versi PS atau konflik plug-in. Penyelesaiannya ialah: Semak saiz fail dan integriti, tingkatkan memori, menaik taraf cakera keras, mengemas kini pemacu kad grafik, menyahpasang atau melumpuhkan pemalam yang mencurigakan, dan memasang semula PS. Masalah ini dapat diselesaikan dengan berkesan dengan memeriksa secara beransur -ansur dan memanfaatkan tetapan prestasi PS yang baik dan membangunkan tabiat pengurusan fail yang baik.
