• 【Python知识】谈谈Python的抽象类


    一、提要

            一个抽象类可以被认为是其他类的蓝图。它允许您创建一组必须在从抽象类构建的任何子类中创建的方法。包含一个或多个抽象方法的类称为抽象类。抽象方法是具有声明但没有实现的方法。在设计大型功能单元时,我们使用抽象类。当我们想为组件的不同实现提供通用接口时,我们使用抽象类。

    二、在Python用抽象类

    2.1 为什么使用抽象基类

            通过定义一个抽象基类,您可以为一组子类定义一个通用的应用程序接口(API)。此功能在第三方将提供实现的情况下特别有用,例如使用插件,但也可以在大型团队或大型代码库中为您提供帮助,因为您很难记住所有类或不可能。

    2.2 抽象基类如何工作

            默认情况下,Python 不提供抽象类。 Python 附带一个模块,该模块为定义抽象基类(ABC)提供了基础,该模块名称为 ABC。 ABC 的工作方式是将基类的方法装饰为抽象,然后将具体类注册为抽象基的实现。当使用关键字@abstractmethod 修饰时,方法变得抽象。例如 -

    示例1:下面代码表示几何种多边形的抽象类

    1. from abc import ABC, abstractmethod
    2. class Polygon(ABC):
    3. @abstractmethod
    4. def noofsides(self):
    5. pass
    6. class Triangle(Polygon):
    7. # overriding abstract method
    8. def noofsides(self):
    9. print("I have 3 sides")
    10. class Pentagon(Polygon):
    11. # overriding abstract method
    12. def noofsides(self):
    13. print("I have 5 sides")
    14. class Hexagon(Polygon):
    15. # overriding abstract method
    16. def noofsides(self):
    17. print("I have 6 sides")
    18. class Quadrilateral(Polygon):
    19. # overriding abstract method
    20. def noofsides(self):
    21. print("I have 4 sides")
    22. # Driver code
    23. R = Triangle()
    24. R.noofsides()
    25. K = Quadrilateral()
    26. K.noofsides()
    27. R = Pentagon()
    28. R.noofsides()
    29. K = Hexagon()
    30. K.noofsides()

    Output: 
    I have 3 sides

    I have 4 sides

    I have 5 sides

    I have 6 sides

    结论:

    • 用抽象类必须从abc包的ABC获取
    • @abstractmethod指定抽象方法

      
    示例2: 这里加与不加@abstractmethod,似乎没什么差别

    1. # Python program showing
    2. # abstract base class work
    3. from abc import ABC, abstractmethod
    4. class Animal(ABC):
    5.     def move(self):
    6.         pass
    7. class Human(Animal):
    8.     def move(self):
    9.         print("I can walk and run")
    10. class Snake(Animal):
    11.     def move(self):
    12.         print("I can crawl")
    13. class Dog(Animal):
    14.     def move(self):
    15.         print("I can bark")
    16. class Lion(Animal):
    17.     def move(self):
    18.         print("I can roar")
    19.          
    20. # Driver code
    21. R = Human()
    22. R.move()
    23. K = Snake()
    24. K.move()
    25. R = Dog()
    26. R.move()
    27. K = Lion()
    28. K.move()

    Output: 

    I can walk and run
    I can crawl
    I can bark
    I can roar

    结论:

    • 用抽象类从abc包的ABC继承类已经注册为抽象类
    • @abstractmethod指定抽象类
    • 实际抽象类似乎与一般类无异,但将来可能随python的发展而扩张。

    2.3 通过子类化实现

            通过直接从基类子类化,我们可以避免显式注册类的需要。在这种情况下,Python 类管理用于将 PluginImplementation 识别为实现抽象 PluginBase。

     Python3

    1. # Python program showing
    2. # implementation of abstract
    3. # class through subclassing
    4. import abc
    5. class parent:      
    6.     def geeks(self):
    7.         pass
    8. class child(parent):
    9.     def geeks(self):
    10.         print("child class")
    11. # Driver code
    12. print( issubclass(child, parent))
    13. print( isinstance(child(), parent))

    Output: 
    True

    True

            使用直接子类化的一个副作用是,可以通过向基类询问从它派生的已知类的列表来找到插件的所有实现。

      

    2.4 抽象基类中的具体方法

            具体类只包含具体(普通)方法,而抽象类可能同时包含具体方法和抽象方法。具体类提供抽象方法的实现,抽象基类也可以通过 super() 调用方法来提供实现。

    让我们看一下使用 super() 调用方法的示例:

    1. # Python program invoking a
    2. # method using super()
    3. import abc
    4. from abc import ABC, abstractmethod
    5. class R(ABC):
    6.     def rk(self):
    7.         print("Abstract Base Class")
    8. class K(R):
    9.     def rk(self):
    10.         super().rk()
    11.         print("subclass ")
    12. # Driver code
    13. r = K()
    14. r.rk()

    Output: 
    Abstract Base Class

    subclass

    在上面的程序中,我们可以使用 super() 来调用抽象类中的方法。

    2.5 抽象属性

            抽象类除了方法之外还包括属性,您可以通过使用@abstractproperty 定义具体类中的属性。

    # Python program showing

    # abstract properties

    import abc

    from abc import ABC, abstractmethod

    class parent(ABC):

        @abc.abstractproperty

        def geeks(self):

            return "parent class"

    class child(parent):

          

        @property

        def geeks(self):

            return "child class"

      

      

    try:

        r =parent()

        print( r.geeks)

    except Exception as err:

        print (err)

      

    r = child()

    print (r.geeks)

    Output: 
     

    Can't instantiate abstract class parent with abstract methods geeks
    child class

    在上面的示例中,无法实例化 Base 类,因为它只有属性 getter 方法的抽象版本。

    2.6 抽象类实例化

            抽象类是不完整的,因为它们有没有人的方法。如果 python 允许为抽象类创建对象,那么如果有人调用抽象方法,则使用该对象,但没有要调用的实际实现。所以我们使用一个抽象类作为模板,并根据需要,在使用它之前对其进行扩展和构建。由于事实上,抽象类不是具体类,它不能被实例化。当我们为抽象类创建对象时,它会引发错误。 

     Python program showing

    # abstract class cannot

    # be an instantiation

    from abc import ABC,abstractmethod

    class Animal(ABC):

        @abstractmethod

        def move(self):

            pass

    class Human(Animal):

        def move(self):

            print("I can walk and run")

    class Snake(Animal):

        def move(self):

            print("I can crawl")

    class Dog(Animal):

        def move(self):

            print("I can bark")

    class Lion(Animal):

        def move(self):

            print("I can roar")

    c=Animal()

    Output: 

    Traceback (most recent call last):
      File "/home/ffe4267d930f204512b7f501bb1bc489.py", line 19, in 
        c=Animal()
    TypeError: Can't instantiate abstract class Animal with abstract methods move
  • 相关阅读:
    数据脱敏的功能与技术原理【详解】
    外汇天眼:美国10月份成屋销售连续第九个月下降!利率上升和通胀飙涨吓跑潜在买家!
    【强化学习论文合集】ICRA-2022 强化学习论文 | 2022年合集(六)
    免费搜索vs付费搜索:百度谷歌的有力竞争者刚刚出现!
    从前序与中序遍历序列构造二叉树
    联想M7216NWA一体机连接WiFi及手机添加打印机方法
    python运行hhsearch二进制命令的包装器类
    2023考研常识知识之五类数学有哪些区别
    计算机毕业设计Java校园失物招领系统(源码+系统+mysql数据库+Lw文档)
    Swagger配置
  • 原文地址:https://blog.csdn.net/gongdiwudu/article/details/126575358