国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

在Python中定義和使用抽象類的方法

2019-11-25 16:40:42
字體:
來源:轉載
供稿:網友

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

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

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

class Sheep(object):  def get_size(self):    raise NotImplementedError

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

import abcclass 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元類來創(chuàng)建一個抽象類, 使用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 abcclass 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 NotTmplementdclass B(object):  def say(self):    return 'hello'print issubclass(B, A)   # Trueprint isinstance(B(), A)  # Trueprint 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 StringIOclass 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 responseinput = StringIO("""line oneline twoline three""")reader = B()print reader.retrieve_values(input)

打印結果

base class reading datasubclass sorting data['line one', 'line two', 'line three']

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

抽象屬性

import abcclass 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.valueexcept Exception, err:  print 'Error: ', str(err)b = B()print 'B.value', b.value

打印結果,A不能被實例化,因為只有一個抽象的property getter method.

Error: ...print concrete property

定義抽象的讀寫屬性

import abcclass 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.valueexcept Exception, err:  print str(err)try:  b = B()  print b.valueexcept Exception, err:  print str(err)c = C()print c.valuec.value = 'hello'print c.value

打印結果, 定義具體類的property時必須與抽象的abstract property相同。如果只覆蓋其中一個將不會工作.

error: ...error: ...print 'default value'print 'hello'

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

import abcclass 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 = _valueb = B()print b.value    # print 'default'b.value = 'hello'print b.value    # print 'hello'

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 保康县| 如皋市| 防城港市| 闵行区| 长春市| 瓦房店市| 甘洛县| 南阳市| 泽库县| 乌海市| 祁连县| 南京市| 三都| 隆林| 油尖旺区| 邯郸市| 临邑县| 绥滨县| 四子王旗| 白银市| 赫章县| 穆棱市| 河源市| 湾仔区| 永修县| 漳浦县| 沛县| 金华市| 金坛市| 青冈县| 金昌市| 常宁市| 诏安县| 马公市| 西盟| 庐江县| 芷江| 全南县| 新建县| 图们市| 阳信县|