Python 设计模式

一、基础概念

ABC抽象基类

abc 模块是 Python 中的抽象基类库。它定义了一个抽象基类(Abstract Base Class,ABC)和相关的工具,用于实现面向对象编程中的多态性和可扩展性

使用 ABC 的主要目的是定义抽象类,抽象类是一种不能被直接实例化的类,它只能被继承。抽象类通常用于定义一个通用的接口,这个接口中定义了一些方法,但是这些方法没有具体的实现。子类可以继承抽象类,并实现抽象类中定义的方法,从而实现多态性。

ABC 模块中定义了 ABCMeta 类,它是抽象类的元类。每个抽象类都必须继承自 ABCMeta,并在其定义中使用 metaclass 关键字进行声明。ABCMeta 类定义了一些方法和属性,用于检查一个类是否是抽象类,以及管理抽象方法和抽象属性。

此外,abc 模块中还定义了一些其他的工具,例如 abstractmethod 函数装饰器,用于定义抽象方法;register 函数,用于将 ABC 注册到 ABC 系统中;isabstractmethod 函数,用于检查一个方法是否是抽象方法。

总之,abc 模块是 Python 中用于实现抽象类和多态性的重要工具,它可以帮助我们更好地组织和管理代码,提高代码的可读性和可维护性

实践

"from abc import ABCMeta, abstractmethod" 是 Python 中的一句导入语句,它的作用是从 abc 模块中导入 ABCMeta 类和 abstractmethod 函数。

ABCMeta 是一个元类,用于定义抽象类。抽象类是一种不能被直接实例化的类,它只能被继承。ABCMeta 定义了抽象类的基本特性,例如如何检查一个类是否是抽象类,以及如何定义抽象方法。

abstractmethod 是一个函数装饰器,用于定义抽象方法。抽象方法是一种没有具体实现的方法,它只能在子类中被实现。abstractmethod 装饰器告诉 Python 解释器,这个方法是抽象方法,需要在子类中实现。

例如:

from abc import ABCMeta, abstractmethod

class MyAbstractClass(metaclass=ABCMeta):
    @abstractmethod
    def my_abstract_method(self):
        pass

class MyConcreteClass(MyAbstractClass):
    def my_abstract_method(self):
        print("Concrete implementation of my_abstract_method.")

在这个例子中,MyAbstractClass 是一个抽象类,它使用了 ABCMeta 作为元类,并定义了一个抽象方法 my_abstract_methodMyConcreteClassMyAbstractClass 的子类,它实现了 my_abstract_method 方法。

导入 ABCMetaabstractmethod 的目的是为了使用它们来定义抽象类和抽象方法,从而实现面向对象编程中的多态性和继承性。

设计模式

工厂方法

# -*- coding: utf-8 -*-
"""
@File   : factory_method.py
@Author : kaiyi
@Date   : 2023/8/20 14:29
@Desc   : 工厂方法模式
"""

from abc import ABCMeta, abstractmethod

class Section(metaclass=ABCMeta):
    @abstractmethod
    def describe(self):
        pass

class PersonalSection(Section):
    def describe(self):
        print("Personal section")

class AlbumSection(Section):
    def describe(self):
        print("Album Section")

#----------------- 抽象类 Creator ----------------
class Profile(metaclass=ABCMeta):
    def __init__(self):
        self.sections = []
        self.createProfile()

    @abstractmethod
    def createProfile(self):
        pass

    def getSections(self):
        return self.sections

    def addSections(self, section):
        self.sections.append(section)

class linkedin(Profile):
    def createProfile(self):
        self.addSections(PersonalSection())

class facebook(Profile):
    def createProfile(self):
        self.addSections(AlbumSection())

if __name__ == '__main__':
    profile_type = input('which profile you like to create? [LinkedIn or Facebook]')

    profile = eval(profile_type.lower())()

    print("creating profile...", type(profile).__name__)
    print("profile has section ---", profile.getSections())

打印:

D:\software\anaconda\djtest\Scripts\python.exe D:\Code\djtest\designPatterns\02factory\factory_method.py 
which profile you like to create? [LinkedIn or Facebook]facebook
creating profile... facebook
profile has section --- [<__main__.AlbumSection object at 0x0000023AB423A940>]

Process finished with exit code 0

为者常成,行者常至