Python雾里看花-抽象类ABC (abstract base class)

版权声明:本文为博主原创文章,转载文章须附上文章来源与作者。 https://blog.csdn.net/ChangerJJLee/article/details/82355872

首先认识模块 abc,python中没有提供抽象类与抽象方法,然而提供了内置模块abc来模拟实现抽象类,例如提供泛映射类型的抽象类 abc.MutableMapping

  • 继承abc.MutableMapping构造一个泛映射类型(类似python中的dict)
# -*- coding: utf-8 -*-
from collections import abc


class MyDic(abc.MutableMapping):

    def __init__(self):
        pass

    def __setitem__(self, key, value):
        print ('key: %s  val: %s' % (key, value))

    def __delitem__(self, key):
        print ('key: %s ' % key)

    def __getitem__(self, item):
        print ('item: %s ' % str(item))

    def __iter__(self):
        pass

    def __len__(self):
        pass
  • 当然继承abc.Mapping 也可以,毕竟MutableMapping是其子类

这里写图片描述

  • dict是python中典型的映射类型数据结构,其接口的定义形式也来自abc.Mapping和abc.MutableMapping这俩种抽象类
# -*- coding: utf-8 -*-
from collections import abc


if __name__ == '__main__':
    mydic = dict()
    print( issubclass(dict, abc.MutableMapping))
    print( issubclass(dict, abc.Mapping))
    print( isinstance(mydic, abc.MutableMapping))
    print( isinstance(mydic, abc.Mapping))
  • 运行结果
True
True
True
True

关于abc的通用模块

  • abc.ABCMeta 用来生成抽象基础类的元类。由它生成的类可以被直接继承,如下是以注册的方式使用元类。
# -*- coding: utf-8 -*-
from abc import ABCMeta

"""
生成了一个MyABCDict的抽象基础类,然后再将dict注册成它的虚拟子类。
然后通过issubclass或者isinstance都可以判断出dict确实是出于MyABCDict类
不会出现在类的MRO (Method Resolution Order),因而也不能通过super()来调用抽象方法。
没有实现抽象方法时,实例化时候不会报错,只有在调用时候才会报错。
"""


class MyABCDict(metaclass=ABCMeta):
    pass


if __name__ == '__main__':

    MyABCDict.register(dict)
    print( issubclass(dict, MyABCDict))
    print( isinstance({}, MyABCDict))
  • abc.ABC辅助类,让你可以不用关心元类概念,直接继承它,就有了ABCMeta元类。使用时注意元类冲突
  • @abc.abstractmethod 定义抽象方法,除了这个装饰器,其余装饰器都被deprecated了。

继承方式使用元类

  • 优点:直接从抽象基类派生子类有一个好处,除非子类实现抽象基类的抽象方法,否则子类不能实例化。
import abc

class PluginBase(metaclass= abc.ABCMeta):
    #__metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def do_something(self, input):
        """Do Some thing."""
        return


class SomePlugin(PluginBase):

    def do_something(self, input):
        print('do_something')

if __name__ == '__main__':
    print ('Subclass:', issubclass(SomePlugin, PluginBase))
    print ('Instance:', isinstance(SomePlugin(), PluginBase))
  • 可以通过 subclasshook方法来实现虚拟方法的检查

猜你喜欢

转载自blog.csdn.net/ChangerJJLee/article/details/82355872