前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python抽象基类abc

python抽象基类abc

作者头像
用户2936342
发布2018-08-27 14:32:50
7890
发布2018-08-27 14:32:50
举报
文章被收录于专栏:nummynummy

python中并没有提供抽象类与抽象方法,但是提供了内置模块abc(abstract base class)来模拟实现抽象类。

可以通过abc将基类声明为抽象类的方式,然后注册具体类作为这个基类的实现。

定义抽象类

首先在abc_base.py中定义一个抽象基类PluginBase,这个基类用于保存和加载数据。

代码语言:javascript
复制
import abc

class PluginBase(object):
    __metaclass__ = abc.ABCMeta
    
    @abc.abstractmethod
    def load(self, input):
        """Retrieve data from the input source and return an object."""
        return
    
    @abc.abstractmethod
    def save(self, output, data):
        """Save the data object to the output."""
        return

通过@abc.abstractmethod将方法声明为抽象方法。

注册具体类

然后在abc_register.py中定义一个具体的类:

代码语言:javascript
复制
import abc
from abc_base import PluginBase

class RegisteredImplementation(object):
    
    def load(self, input):
        return input.read()
    
    def save(self, output, data):
        return output.write(data)

PluginBase.register(RegisteredImplementation)

if __name__ == '__main__':
    print 'Subclass:', issubclass(RegisteredImplementation, PluginBase)
    print 'Instance:', isinstance(RegisteredImplementation(), PluginBase)

在上面的例子中,RegisteredImplementation并没有继承自PluginBase,而是将其注册为PluginBase的一个实现。 运行结果如下:

代码语言:javascript
复制
Subclass: True
Instance: True

通过派生实现

也可以在abc_subclass.py中直接继承抽象类:

代码语言:javascript
复制
import abc
from abc_base import PluginBase

class SubclassImplementation(PluginBase):
    
    def load(self, input):
        return input.read()
    
    def save(self, output, data):
        return output.write(data)

if __name__ == '__main__':
    print 'Subclass:', issubclass(SubclassImplementation, PluginBase)
    print 'Instance:', isinstance(SubclassImplementation(), PluginBase)

这样做有一个副作用,当查询基类的子类时,会输出所有继承自改类的子类。

代码语言:javascript
复制
import abc
from abc_base import PluginBase
import abc_subclass
import abc_register

for sc in PluginBase.__subclasses__():
    print sc.__name__

输出结果如下:

代码语言:javascript
复制
SubclassImplementation

不完整的实现

直接从抽象基类派生子类有一个好处,除非子类完全抽象基类的抽象方法,否则子类不能实例化。

代码语言:javascript
复制
import abc
from abc_base import PluginBase

class IncompleteImplementation(PluginBase):
    
    def save(self, output, data):
        return output.write(data)

if __name__ == '__main__':
    print 'Subclass:', issubclass(IncompleteImplementation, PluginBase)
    print 'Instance:', isinstance(IncompleteImplementation(), PluginBase)

ABC中的具体方法

尽管具体子类必须实现抽象类中的所有抽象方法,但是,抽象类中也可以包含具体方法。在子类中可以通过super()来调用。

代码语言:javascript
复制
import abc
from cStringIO import StringIO

class ABCWithConcreteImplementation(object):
    __metaclass__ = abc.ABCMeta
    
    @abc.abstractmethod
    def retrieve_values(self, input):
        print 'base class reading data'
        return input.read()

class ConcreteOverride(ABCWithConcreteImplementation):
    
    def retrieve_values(self, input):
        base_data = super(ConcreteOverride, self).retrieve_values(input)
        print 'subclass sorting data'
        response = sorted(base_data.splitlines())
        return response

input = StringIO("""line one
line two
line three
""")

reader = ConcreteOverride()
print reader.retrieve_values(input)
print

输出结果如下:

代码语言:javascript
复制
base class reading data
subclass sorting data
['line one', 'line three', 'line two']

抽象属性

可以通过@abstractproperty定义抽象属性:

代码语言:javascript
复制
import abc

class Base(object):
    __metaclass__ = abc.ABCMeta
    
    @abc.abstractproperty
    def value(self):
        return 'Should never get here'


class Implementation(Base):
    
    @property
    def value(self):
        return 'concrete property'


try:
    b = Base()
    print 'Base.value:', b.value
except Exception, err:
    print 'ERROR:', str(err)

i = Implementation()
print 'Implementation.value:', i.value

输出结果如下:

代码语言:javascript
复制
ERROR: Can't instantiate abstract class Base with abstract methods value
Implementation.value: concrete property
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.10.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 定义抽象类
  • 注册具体类
  • 通过派生实现
  • 不完整的实现
  • ABC中的具体方法
  • 抽象属性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档