精华内容
下载资源
问答
  • Python 抽象基类的理解

    千次阅读 2019-07-03 18:02:10
    2.抽象基类无法实例化 以上两个特点,主要用于接口设计 注意:Python中并没有提供抽象类与抽象方法,但是提供了内置模块abc来模拟实现抽象类 二、使用场景: 1.判断某个对象的类型: class ColorObj(object): ""...

    Python 抽象基类的理解

    一、抽象基类的特点:

    1.规定继承类必须具有抽象基类指定的方法

    2.抽象基类无法实例化

    以上两个特点,主要用于接口设计

    注意:Python中并没有提供抽象类与抽象方法,但是提供了内置模块abc来模拟实现抽象类

    二、使用场景:

    1.判断某个对象的类型:

    class ColorObj(object):
        """创建一个颜色的类"""
    
        def __init__(self, color_list):
            """初始化方法"""
            self.color = color_list
    
        def __len__(self):
            return len(self.color)
    
    
    color = ColorObj(['red', 'yellow', 'blue'])
    
    from collections.abc import Sized
    result = isinstance(color, Sized)
    print(result)
    
    # 输出结果: True
    
    • isinstance 用来判断一个对象的实例,Color都没有继承Sized,可是为什么会返回True,这些就可以想到鸭子类型(是动态类型的一种风格),下面看一下Sized的源码:

      class Sized(metaclass=ABCMeta):
      
          __slots__ = ()
      
          @abstractmethod
          def __len__(self): 
              return 0
      
          @classmethod
          def __subclasshook__(cls, C):
              if cls is Sized:
                  return _check_methods(C, "__len__")
              return NotImplemented
      

      解释:这个Sized的抽象基类,它会继承metaclass=ABCMeta, 并且@abstractmethod 抽象方法,关键判断它是否有__ len __ 方法在于下面的 __ subclasshook __ 魔法方法。

    2.强制子类必须实现某些方法:

    • 首先看一下,上面所说的特点抽象基类无法实例化:

      import abc
      
      class BaseObj(metaclass=abc.ABCMeta):
          """基类"""
      
          @abc.abstractmethod  # 给该方法添加装饰器
          def get(self, value):
              print(value)
      
          @abc.abstractmethod
          def set(self, key, value):
              print(key, value)
      
      
      base_obj = BaseObj()  # 实例化BaseObj的时候报错
      print(base_obj)
      
      # 报错信息:
      Traceback (most recent call last):
        File "C:/Users/lh9/PycharmProjects/request/Python魔法函数.py", line 121, in <module>
          base_obj = BaseObj()
      TypeError: Can't instantiate abstract class BaseObj with abstract methods get, set
      
    • 强制子类实现的方法:

      class BaseObj(metaclass=abc.ABCMeta):
          """基类"""
      
          @abc.abstractmethod
          def get(self, value):
              print(value)
      
          @abc.abstractmethod
          def set(self, key, value):
              print(key, value)
      
      
      class Dog(BaseObj):
      
          def get(self, value):
              print(value)
      
      
      dog = Dog()
      print(dog.get('fe_cow'))
      
      # 输出结果会报错:
      Traceback (most recent call last):
        File "C:/Users/lh9/PycharmProjects/request/Python魔法函数.py", line 127, in <module>
          dog = Dog()
      TypeError: Can't instantiate abstract class Dog with abstract methods set
      

      报错原因:因为我们继承的BaseObj类中,get、set方法都添加了装饰器@abc.abstractmethod,说明要继承BaseObj的子类,必须要实现get、set方法,否则会报错。

      class BaseObj(metaclass=abc.ABCMeta):
          """基类"""
      
          @abc.abstractmethod
          def get(self, value):
              print(value)
      
          @abc.abstractmethod
          def set(self, key, value):
              print(key, value)
      
      
      class Dog(BaseObj):
      
          def get(self, value):
              print(value)
              return value
      
          def set(self, key, value):
              pass
      
      dog = Dog()
      print(dog.get('fe_cow'))
      
      # 输出结果:
      fe_cow
      fe_cow
      

    三、collection.abc模块常用的抽象基类:

    __all__ = ["Awaitable", "Coroutine",
               "AsyncIterable", "AsyncIterator", "AsyncGenerator",
               "Hashable", "Iterable", "Iterator", "Generator", "Reversible",
               "Sized", "Container", "Callable", "Collection",
               "Set", "MutableSet",
               "Mapping", "MutableMapping",
               "MappingView", "KeysView", "ItemsView", "ValuesView",
               "Sequence", "MutableSequence",
               "ByteString",
               ]
    

    感兴趣的可以看看这些源码

    展开全文
  • python抽象基类理解

    2020-03-12 20:19:02
    (what)什么是抽象基类? ...2.抽象基类无法实例化 (why)为什么要有抽象基类这玩意? 1.why 抽象基类? 譬如要开发一个项目,你要规定项目开发者要去完成某些接口,这时候抽象基类就帮上忙了,你...

    (what)什么是抽象基类?

    抽象基类它提供了接口,但是又没有去把接口实现的类,需要由子类完成。感觉它就是老板,只告诉你要完成项目A, 你接到项目A后(继承),你自己去把它完成。
    抽象基类特点:
    1.继承类必须实现抽象基类的方法
    2.抽象基类无法实例化

    (why)为什么要有抽象基类这玩意?

    1.why 抽象基类?
    譬如要开发一个项目,你要规定项目开发者要去完成某些接口,有些接口会不会忘记实现了呢?你在担心…这时候抽象基类就帮上忙了,你可以给开发者提供抽象基类,因为它必须让继承它的子类去实现它所要求的方法(这个例子不知道牵强不?)。当然也有其他的优点:处理继承问题方面更加规范、系统,明确调用之间的相互关系,使得继承层次更加清晰。

    2.为什么抽象基类用collections.abc?
    假设我们要编写一种对象,本身虽然不属于list子类,但是却要让它可以像list那样子去访问。例如我们现在想让一颗二叉树可以像list那样子访问,那么我们要实现__geitem__(),要实现__len__(),这个还不完整,还要实现index, count方法,要实现那么多方法很复杂,用collections.abc模块的话,实现了抽象基类所要求的方法,模块会自动实现剩下的那些方法。

    (how)如何使用?

    我们一般都不会自己去定义抽象基类,而是使用collections.abc模块
    例如:

    import abc
    
    class A(abc.ABC):#自己定义一个抽象基类,
        @abc.abstractmethod
        def eat(self):
            pass
        
    class B(A):#继承抽象基类
        def voice(self):
            pass
            
    if __name__ == "__main__":
        a = A() 
    #报错,抽象类无法实现实例化
    #TypeError: Can't instantiate abstract class A with abstract methods eat
        a = B()
        a.eat()
    #报错,继承类必须实现抽象类的方法
    #TypeError: Can't instantiate abstract class B with abstract methods eat
    

    又如:

    from collections import abc
    
    class A(abc.Sequence): #继承抽象基类abc,Sequece
        def eat(self):
            pass
        
    class B(A):
        def __getitem__(self): #必须实现__getitem__()
            pass
        def __len__(self):  #必须实现__len__()
            pass
        def voice(self):
            pass
    if __name__ == "__main__":
        b = B()
    
    展开全文
  • Python抽象基类

    2020-06-19 17:09:22
    1.抽象基类的定义 ...抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化。 3.抽象基类应用场景 3.1 检查某个类中是否有某种方法 判断 Demo中 是

    1.抽象基类的定义

    抽象基类(abstract base class,ABC):抽象基类就是类里定义了纯虚成员函数的类,纯虚函数只提供了接口,并没有具体实现。

    2.抽象基类的特点

    • 不能被实例化

    抽象基类不能被实例化(不能创建对象),通常是作为基类供子类继承,子类中重写虚函数,实现具体的接口。

    • 子类必须实现抽象基类的方法

    抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化。

    3.抽象基类应用场景

    3.1 检查某个类中是否有某种方法

    判断 Demo中 是否 含有 __len__魔法方法

    class Demo(object):
        def __init__(self,list):
            self.list = list
        def __len__(self):
            return len(self.list)
    
    d = Demo(["CW","ls",'age'])
    
    from collections.abc import Sized  #导入模块collections.abc的Sized类
    print(hasattr(Sized,"__len__")) # 判断d的内部 是否含有__len__ ,返回值为布尔值,结果为true
    print(isinstance(d,Sized))   # 检查d是否Sized类型 结果为:True
    

    Sized源码如下:

    class Sized(metaclass=ABCMeta):
    
        __slots__ = ()
        @abstractmethod
        def __len__(self):
            return 0
        @classmethod
        def __subclasshook__(cls, C):
            if cls is Sized:
                return _check_methods(C, "__len__")
            return NotImplemented
    

    3.2 强制子类必须实现父类的方法

    3.2.1 方法一:主动抛出异常

    如下实例,子类RedisBase中未重写crea方法,在实例化子类RedisBase,没有报错,在调用crea()方法时报错:

    class CacheBase(object):
    
        def dele(self):
            raise NotImplementedError
    
        def crea(self):
            raise NotImplementedError
    
    class RedisBase(CacheBase):
    
        def dele(self):
            print('I will delete')
    
        # def crea(self):
        #     print('I will create')
    
    r = RedisBase() 
    r.crea() #raise NotImplementedError
    r.dele() 
    

    3.2.2 方法二:抽象基类实现

    如下实例中,子类RedisBase中未重写crea方法,在实例化子类RedisBase时就报错:

    import abc
    class BaseClass(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def dele(self):
            pass
        @abc.abstractmethod
        def crea(self):
            pass
            
    class SubClass(BaseClass):
         def dele(self):
             print('I will delete')
         # def crea(self):
         #     print('I will create')
    r = SubClass() # TypeError: Can't instantiate abstract class SubClass with abstract methods crea
    r.dele()
    r.crea()
    

    3.2.3 两种方法对比

    • 主动抛出异常 :调用时才会检测
    • 抽象基类 : 实例化的时候检测
    展开全文
  • 抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化。 起名字时不要把模块名起为abc.py,因为abc基类的原因,那时候就会冲突 应用场景: 1.我们去检查某个类中...

    抽象基类(abc模块)
    抽象基类介绍
    抽象基类(abstract base class,ABC):抽象基类就是类里定义了纯虚成员函数的类。纯虚函数只提供了接口,并没有具体实现。抽象基类不能被实例化(不能创建对象),通常是作为基类供子类继承,子类中重写虚函数,实现具体的接口。
    抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化。
    起名字时不要把模块名起为abc.py,因为abc基类的原因,那时候就会冲突
    应用场景:
    1.我们去检查某个类中是否有某种方法
    2.我们需要强调某个子类必须实现某些方法

    • 1.检查某个类中是否有某种方法:
    • 以len为例子
    • 一种方式是通过反射实现的:
    class Demo(object):
        def __init__(self,li):
            self.li = li
    
        def __len__(self):
            return len(self.li)
    
    
    l = ['a','n','c']
    d = Demo(l)
    print(len(d))   #触发return len(self.li)   返回了3
    print(d.li)
    
    #如何判断一个类中是否有某个属性?
    print(hasattr(d,'__len__'))
    

    第二种方式是通过抽象基类实现的:

    class Demo(object):
        def __init__(self,li):
            self.li = li
    
        def __len__(self):
            return len(self.li)
    
    
    l = ['a','n','c']
    d = Demo(l)
    print(len(d))   #触发return len(self.li)   返回了3
    print(d.li)
    
    
    
    from _collections_abc import Sized
    print(isinstance(d,Sized))
    
    #可以通过判断d是Sized的子类进而判断d是否含有len方法
    #_collections_abc.py中搜Sized
    # @classmethod
    #     def __subclasshook__(cls, C):
    #         if cls is Sized:
    #             return _check_methods(C, "__len__")
    #         return NotImplemented
    
    
    

    可以通过判断d是Sized的子类进而判断d是否含有len方法
    因为在这个定义中Sized的子类都含有len方法,是Sized的子类就含有len方法
    _collections_abc位置:
    /python路径/Lib/_collections_abc.py 不过该文件为隐藏文件,需要看时要设置查看隐藏文件

    2.我们需要强调某个子类必须实现某些方法
    如果没有重写某个方法的话就会抛出异常
    实现的方式:
    第一种方式:在父类定义,设置主动抛出异常
    第二种方式:在父类中通过继承抽象基类实现抛异常

    第一种方式代码:

    '''
    强制子类必须实现父类的方法
    • 定义父类Cache
    • 封装CRUD方法。强制子类重写该方法。
    子类如果不重写该方法,就会报错
    • 定义子类Redis
    方式1:利用抛异常的方式
    
    '''
    
    class Cache(object):
    
        def dele(self):
            pass
            #raise NotImplementedError
    
        def crea(self):
    
            raise NotImplementedError
    
    class Redis(Cache):
        def crea(self):
            pass
    
    r = Redis()
    r.crea()
    r.dele()
    

    这种实现方式有其固有的缺点:只有当调用该方法时才会抛出异常,在实例化的时候 并不会有提示

    第2种方式:
    通过继承抽象基类的方式:

    #此时只要新建实例,如果没有重写就会报错,而第一种的抛异常只有我们访问这个方法时才抛出异常,如果不访问就不会有影响
    #抽象基类的方式   在实例化时如果发现没有重写就会抛出异常
    
    import abc
    
    class Cache(metaclass=abc.ABCMeta):
        #直接继承抽象基类
        #装饰器
        @abc.abstractmethod
        def dele(self):
            pass
            #raise NotImplementedError
    
        def crea(self):
            pass
            #raise NotImplementedError
    
    class Redis(Cache):
        def crea(self):
            print('lcy')
    
        def dele(self):
            print('dele')
    
    r = Redis()
    
    展开全文
  • 抽象基类有两个特点:规定继承类必须具有抽象基类指定的方法、抽象基类无法实例化。基于这两个特点,抽象基类主要用于接口设计。 使用模块abc可创建抽象基类。使用@abstractmethod来将方法标记为抽象的,即在子类中...
  • 抽象基类就是定义各种方法而不做具体实现的类,任何继承自抽象基类的类必须实现这些方法,否则无法实例化抽象基类不能被实例化(不能创建对象),通常是作为基类供子类继承,子类中重写虚函数,实现具体的接口。...
  • Python总结-(抽象基类)

    2020-04-08 14:33:46
    抽象基类不能被实例化,通常是作为基类供子类继承,子类中重写虚函数,实现具体的接口 在C++中,派生类需要重写基类中的所有虚函数,不然是无法创建对象的,python怎样实现抽象基类呢? class A(object): def get...
  • 3.抽象基类

    2021-02-12 15:20:36
    2)抽象基类无法实例化。 3)当我们想要子类必须实现某些方法的时候,可以使用抽象基类。 模拟一个抽象基类: 下图看到 当rediscache调用基类set方法的时候就会抛出异常,因为基类没有覆盖set方法。 那怎样才能让...
  • 一、定义 抽象基类(abstract base class, ABC)用来确保派生类中实现了基类中的特定方法...基类无法实例化 如果在子类中忘记实现接口方法,需要尽早报错 二、设计 现在,我们自己来设计一个抽象类 class Base: de...
  • 了解Java的开发者对接口不会陌生,Java无法进行...与Java接口类似,Python抽象基类无法进行实例化,强制实例化会抛出异常 from abc import abstractmethod,ABCMeta class AbstractBaseHandler(metaclass=ABCMeta) :
  • 所以如果不实现抽象了的的方法属性,对象无法实例化。 所有为抽象属性方法提供具体实现的类都是抽象基类的子类 分类: 内置的,大多数存在于colletions模块 https://www.cnblogs.com/dianel/p/10787693.html ...
  • 接口不能用来实例化的,因此,python终端抽象基类也是不可用实例化的。 Python是动态语言,是没有变量的类型的,在python中,变量只是一个符号而已,它是可以指向任何类型的对象,因此python中也不存在多态这个概念...
  • 1.抽象类概念 抽象类是一个特殊的类,只能被继承,不能实例化 2.为什么要有抽象类 ...但是我们却不能将水果实例化,因为我们无法吃到叫水果的这个东西。 所以抽象类中只能有抽象方法(没有实现功能),该类...
  • 1、抽象类概念  抽象类是一个特殊的类,只能被继承,不能实例化 2、为什么要有抽象类  其实在未接触抽象类...但是我们却不能将水果实例化,因为我们无法吃到叫水果的这个东西。  所以抽象类中只能有抽象方...
  • 1什么是抽象抽象类是一个特殊的类,只能被继承,不能实例化 2为什么只能被继承,不能实例化 ...但是我们却不能将水果实例化,因为我们无法吃到叫水果的这个东西。 所以抽象类中只能有抽象方法(没有...
  • 1.抽象类概念 抽象类是一个特殊的类,只能...但是我们却不能将水果实例化,因为我们无法吃到叫水果的这个东西。 所以抽象类中只能有抽象方法(没有实现功能),该类不能被实例化,只能被继承,且子类必须实现抽象方法。
  • Python学习 - 之ABC模块

    2019-01-15 13:05:00
    abc模块是AbsructBaseClass的缩写概念: 可以把抽象基类当作java里面的接口,在java里无法实现多继承,但是可以实现多接口, 接口是不能用来实例化的,Python里面的抽象基类也是不能实例化的,python中变量只是一个...
  • 在Java语言里面有接口和抽象基类的概念,在Python里面用类也能够实现。 抽象类无法实例化,而且规定的抽象方法都是需要在子类中实现,具体方法就会有默认的实现。 from abc import ABC, abstractmethod class ...
  • Python小知识点随笔

    2020-11-13 23:34:22
    如果某个类的metaclass是abc.ABCMeta,那么该类就无法初始化,只能把它当成抽象基类来使用; 继承的子类,必须实现父类的所有抽象方法,否则子类实例化时会报错; 使用abc模块中的@abstractmethod装饰器,能够使类中...
  • 类的多态性

    2020-05-14 01:09:43
    1 、 Python抽象类 1.抽象类概念 抽象类是一个特殊的类,只能被继承,不能实例化 2.为什么要有抽象类 其实在未接触抽象类概念时,我们可以构造香蕉、苹果、梨之类的类,然后让它们继承水果这个的基类,水果的基类...

空空如也

空空如也

1 2
收藏数 24
精华内容 9
关键字:

python抽象基类无法实例化

python 订阅