日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

在Python中定义和使用抽象类的方法

發布時間:2025/3/8 python 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Python中定义和使用抽象类的方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

https://www.jb51.net/article/87710.htm

?

像java一樣python也可以定義一個抽象類。

在講抽象類之前,先說下抽象方法的實現。

抽象方法是基類中定義的方法,但卻沒有任何實現。在java中,可以把方法申明成一個接口。而在python中實現一個抽象方法的簡單的方法是:

?
1 2 3 class Sheep(object): ??def get_size(self): ????raise NotImplementedError

任何從Sheep繼承下來的子類必須實現get_size方法。否則就會產生一個錯誤。但這種實現方法有個缺點。定義的子類只有調用那個方法時才會拋錯。這里有個簡單方法可以在類被實例化后觸發它。使用python提供的abc模塊。

?
1 2 3 4 5 6 7 import abc class Sheep(object): ??__metaclass__ = abc.ABCMeta ??? ??@abc.absractmethod ??def get_size(self): ????return


這里實例化Sheep類或任意從其繼承的子類(未實現get_size)時候都會拋出異常。

因此,通過定義抽象類,可以定義子類的共同method(強制其實現)。

如何使用抽象類

?
1 2 3 4 5 6 7 8 9 10 11 12 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裝飾器來表明抽象方法

注冊具體類

?
1 2 3 4 5 6 7 8 9 10 11 12 13 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

從抽象類注冊一個具體的類

子類化實現

?
1 2 3 4 5 6 7 8 9 10 11 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. 但是副作用是可以通過基類找出所有的具體類

?
1 2 3 4 for sc in A.__subclasses__(): ??print sc.__name__ # print C

如果使用繼承的方式會找出所有的具體類,如果使用register的方式則不會被找出

使用__subclasshook__

使用__subclasshook__后只要具體類定義了與抽象類相同的方法就認為是他的子類

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 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

不完整的實現

?
1 2 3 4 5 6 7 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不能實例化抽象類和抽象方法

具體類中使用抽象基類

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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)

打印結果

?
1 2 3 base class reading data subclass sorting data ['line one', 'line two', 'line three']

可以使用super來重用抽象基類中的羅輯, 但會迫使子類提供覆蓋方法.

抽象屬性

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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.

?
1 2 Error: ... print concrete property

定義抽象的讀寫屬性

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 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相同。如果只覆蓋其中一個將不會工作.

?
1 2 3 4 error: ... error: ... print 'default value' print 'hello'

使用裝飾器語法來實現讀寫的抽象屬性, 讀和寫的方法應該相同.

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 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中定义和使用抽象类的方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。