行为型模式 (Python版)

Python语言 的设计模式(Design Patterns) 设计模式是软件开发过程中重要的组成部分。通过合理运用设计模式,可以提高代码的可读性、可维护性和可重用性,促进软件开发的灵活性和敏捷性。对于Python开发者而言,理解常用的设计模式将为其构建高质量的软件系统打下坚实的基础。在实际开发中,选择合适的设计模式并不是一件容易的事,因此开发者需要根据具体的业务需求、项目规模和团队经验来做出决策。希望通过本文的介绍,能够帮助读者更好地理解和运用设计模式。 阅读详情

模板方法模式

"""
    案例:写简历
    内容:
        最近有个招聘会,可以带上简历去应聘了。
        但是,其中有一家公司不接受简历,
        而是给应聘者发了两张公司自己定制的简历表,分别是A类型的简历表和B类型的简历表
        这两张表上面都有差不多的内容:基本信息、教育背景、工作经历,
        让应聘者选择其中一种类型的简历表,按照要求填写完整。
        每个人拿到这份表格后,就开始填写。
        如果用程序实现这个过程,该如何做呢?
        一种方案就是用模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
        模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
"""

from abc import ABC, abstractmethod


# 简历表(抽象类)
class ResumeTable(ABC):

    @abstractmethod
    def _write_basic_info(self):  # 写基本信息(抽象)
        pass

    @abstractmethod
    def _write_education(self):  # 写教育背景(抽象)
        pass

    @abstractmethod
    def _write_work_experience(self):  # 写工作经历(抽象)
        pass

    # 填写简历的全过程(模板)
    def fill_resume(self):
        self._write_basic_info()  # 先写基本信息
        self._write_education()  # 再写教育背景
        self._write_work_experience()  # 然后写工作经历


# A类型的简历表
class ResumeTableA(ResumeTable):

    def _write_basic_info(self):
        print("简历A: 基本信息, ", end="")

    def _write_education(self):
        print("教育背景, ", end="")

    def _write_work_experience(self):
        print("工作经验 (越简单越好).")


# B类型的简历表
class ResumeTableB(ResumeTable):

    def _write_basic_info(self):
        print("简历B: 基本信息, ", end="")

    def _write_education(self):
        print("教育背景, ", end="")

    def _write_work_experience(self):
        print("工作经验 (越详细越好).")


if __name__ == '__main__':
    # 填写类型A的简历表
    a = ResumeTableA()
    a.fill_resume()

    # 填写类型B的简历表
    b = ResumeTableB()
    b.fill_resume()

命令模式

"""
    案例:客人点餐
        1. 客人发出命令,让厨师做饭
        2. 客人发出命令,让厨师取消做饭
        3. 客人发出命令,让厨师煮面
        4. 客人发出命令,让厨师取消煮面
"""

from abc import ABC, abstractmethod


# 厨师(具体类)
class Chef:  # 厨师有以下四种能力

    # 做饭
    def make_meals(self):
        print("做饭")

    # 取消做饭
    def cancel_meals(self):
        print("取消做饭")

    # 煮面
    def make_noodles(self):
        print("煮面")

    # 取消煮面
    def cancel_noodles(self):
        print("取消煮面")


# 命令(抽象类)
class Command(ABC):

    def __init__(self):
        self.__chef = None  # 存放(维护)一个厨师对象

    @abstractmethod
    def execute_command(self):  # 执行命令(抽象)
        pass

    @abstractmethod
    def cancel_command(self):  # 取消执行命令(抽象)
        pass


# 关于做饭的命令(具体类)
class AboutMealsCommand(Command):

    def __init__(self, chef: Chef):
        super().__init__()
        self.__chef = chef

    def execute_command(self):
        print("快点去给我", end="")
        self.__chef.make_meals()

    def cancel_command(self):
        print("我不要了,", end="")
        self.__chef.cancel_meals()


# 关于煮面的命令(具体类)
class AboutNoodlesCommand(Command):

    def __init__(self, chef: Chef):
        super().__init__()
        self.__chef = chef

    def execute_command(self):
        print("快点去给我", end="")
        self.__chef.make_noodles()

    def cancel_command(self):
        print("我不要了,", end="")
        self.__chef.cancel_noodles()


# 客人(具体类)
class Customer:

    # 客人想一些命令
    def think_command(self, command: Command):
        self.__command = command

    # 客人说话(发出命令),说想要吃
    def speak_to_eat(self):
        self.__command.execute_command()

    # 客人说话(发出命令),说不想吃了
    def speak_to_cancel(self):
        self.__command.cancel_command()


if __name__ == '__main__':
    # 招聘一个厨师
    chef = Chef()

    # 与厨师约定好"做饭"和"煮面"相关的命令
    about_meals_command = AboutMealsCommand(chef)
    about_noodles_command = AboutNoodlesCommand(chef)

    # 来了一位顾客
    customer = Customer()

    # 顾客思考一些关于煮饭的命令
    customer.think_command(about_meals_command)

    # 思考完毕,下达命令
    customer.speak_to_eat()  # 说自己想吃(饭)
    customer.speak_to_cancel()  # 说自己不想吃(饭)了

    # 顾客思考一些关于煮面的命令
    customer.think_command(about_noodles_command)

    # 思考完毕,下达命令
    customer.speak_to_eat()  # 说自己想吃(面)

"""
运行结果:
    快点去给我做饭
    我不要了,取消做饭
    快点去给我煮面
"""

责任链模式

"""
    案例:员工请假
    内容:
        当员工申请请假1天以内,由组长批准即可(处理者为组长)
        当员工申请请假超过3天,需要由经理批准(处理者为经理)
        当员工申请请假超过7天,需要由老板批准(处理者为老板)
"""

from abc import ABC, abstractmethod


# 处理者(抽象类)
class Handler(ABC):

    def __init__(self):
        self._next_handler = None  # 用于存放下一个处理者

    # 设置下一个处理者是谁
    def set_next_handler(self, next_handler):
        self._next_handler = next_handler

    # 处理请求(先尝试自己的处理,如果处理不了,会将请求交给下一个处理者进行处理)
    @abstractmethod
    def handle_request(self, days):
        pass


# 组长(具体类)
class GroupLeader(Handler):

    def handle_request(self, days: int):
        print("组长:", end="")
        if days <= 3:
            print("同意请假!")
        else:
            print("请假太久了,你去找经理请假。")
            if self._next_handler:
                self._next_handler.handle_request(days)


# 经理(具体类)
class Manager(Handler):

    def handle_request(self, days: int):
        print("经理:", end="")
        if days <= 7:
            print("同意请假!")
        else:
            print("请假太久了,你去找老板请假。")
            if self._next_handler:
                self._next_handler.handle_request(days)


# 老板(具体类)
class Boss(Handler):

    def handle_request(self, days: int):
        print("老板:", end="")
        if days <= 10:
            print("同意请假!")
        else:
            print("请假太久了,不同意请假")
            if self._next_handler:
                self._next_handler.handle_request(days)


if __name__ == '__main__':
    # 实例化一个组长、一个经理、一个老板
    group_leader = GroupLeader()
    manager = Manager()
    boss = Boss()

    # 组装链
    group_leader.set_next_handler(manager)
    manager.set_next_handler(boss)

    # -------------------- 请假 --------------------
    day = 3
    print(f"我:想要请假{day}天")
    group_leader.handle_request(day)
    print("-----------------------")

    day = 7
    print(f"我:想要请假{day}天")
    group_leader.handle_request(day)
    print("-----------------------")

    day = 10
    print(f"我:想要请假{day}天")
    group_leader.handle_request(day)
    print("-----------------------")

    day = 30
    print(f"我:想要请假{day}天")
    group_leader.handle_request(day)
    print("-----------------------")

策略模式

from abc import ABC, abstractmethod


# 策略(抽象类)
class Strategy(ABC):

    @abstractmethod
    def execute(self, left: int, right: int):  # 执行策略
        pass


# 加法策略(具体类)
class AddStrategy(Strategy):

    def execute(self, left: int, right: int):
        return left + right


# 减法策略(具体类)
class SubStrategy(Strategy):

    def execute(self, left: int, right: int):
        return left - right


# 乘法策略(具体类)
class MulStrategy(Strategy):

    def execute(self, left: int, right: int):
        return left * right


# 除法策略(具体类)
class DivStrategy(Strategy):

    def execute(self, left: int, right: int):
        if right == 0:
            raise "除数不能为零!"
        return left / right


# 策略容器(具体类)
class Container:

    def __init__(self):
        self.__strategy = None  # 用来保存(维护)一个策略对象

    # 设置策略
    def set_strategy(self, strategy: Strategy):
        self.__strategy = strategy

    # 执行某策略的功能
    def execute_strategy(self, left: int, right: int):
        return self.__strategy.execute(left, right)


if __name__ == '__main__':
    # 实例化一个策略容器
    container = Container()

    # 符号处理的前期准备
    symbol_list = ("+", "-", "*", "/")  # 符号列表
    index = 0  # 符号所在位置的索引(下标)

    while True:
        # 获取用户输入
        expression = input("(Count) >>> ")

        # 解析用户输入
        # 1.符号处理(获取符号索引位置)
        for symbol in symbol_list:
            if symbol in expression:  # 如果当前符号在表达式里面
                index = expression.index(symbol)  # 记录符号在表达式中的索引位置
                break

        # 2.获取左右值(例如 5 + 7 中的左值为5,右值为7)
        left = int(expression[0: index: 1].strip())
        right = int(expression[index + 1: len(expression): 1].strip())

        # 3.根据用户选择,向策略容器里面添加合适的策略
        match expression[index]:
            case "+":
                container.set_strategy(AddStrategy())  # 实例化一个策略,并添加到策略容器中
            case "-":
                container.set_strategy(SubStrategy())  # 实例化一个策略,并添加到策略容器中
            case "*":
                container.set_strategy(MulStrategy())  # 实例化一个策略,并添加到策略容器中
            case "/":
                container.set_strategy(DivStrategy())  # 实例化一个策略,并添加到策略容器中
            case _:
                raise "符号错误!"

        # 4.执行策略容器里面的策略
        print(container.execute_strategy(left, right))

观察者模式

"""
案例:员工摸鱼
通过老板的动作信息(是否出现在公司),员工做出不同的反应(摸鱼或努力工作)
"""

from abc import ABC, abstractmethod


# 实现一个员工类(具体类)
class Employee:

    def __init__(self, name):
        self.__name = name  # 存放员工自己的姓名

    # 结合来自外部的通知信息,更新员工自己的工作状态(摸鱼或认真工作)
    def update(self, info):
        print(f"{self.__name}收到情报:{info},", end="")
        if info == "老板来了":
            print("开启工作模式。")
        elif info == "老板走了":
            print("开启摸鱼模式。")


# 实现一个老板类(具体类)
class Boss:

    def __init__(self):
        self.__employee_list = []  # 存放老板手下的员工对象
        self.__action_plan = ""  # 存放老板的行动计划

    # 老板招聘员工
    def add_employee(self, employee: Employee):
        self.__employee_list.append(employee)

    # 老板设置自己的行动计划
    def set_action_plan(self, plan):
        self.__action_plan = plan
        self._notify(plan)  # 泄密

    # 发出通知
    def _notify(self, plan):
        # 根据老板的计划,设置泄密信息的内容
        info = ""
        if plan == "去巡查一下他们有没有好好工作":
            info = "老板来了"
        elif plan == "坐飞机出个差":
            info = "老板走了"

        # 通知每个员工
        for employee in self.__employee_list:
            employee.update(info)


if __name__ == '__main__':
    # 实例化一个老板(被观察者)
    boss = Boss()

    # 实例化一些员工(观察者)
    emp_1 = Employee("小明")
    emp_2 = Employee("老张")
    emp_3 = Employee("老李")

    # 老板去招聘上面这些员工(建立关联)
    boss.add_employee(emp_1)
    boss.add_employee(emp_2)
    boss.add_employee(emp_3)

    # 老板设置行动计划
    boss.set_action_plan("去巡查一下他们有没有好好工作")
    print("-----------")
    boss.set_action_plan("坐飞机出个差")
    print("-----------")

访问者模式

"""
    案例:
        这里实现一个不同职业的人去医院和餐厅的例子来说明访问者模式
        在小镇上有一个医院和一个餐厅,
        每天都会有不同的人访问这两个地方,
        由于访问者不同到这两个地方要做的事也有区别。
        医生去医院是为了工作给病人看病,
        厨师去医院是为了检查身体,
        医生去餐厅是为了吃饭,
        厨师去餐厅是为了工作给客人烹饪菜肴。
"""

from abc import ABC, abstractmethod


# 地方(抽象类)
class Place(ABC):

    def __init__(self, name: str):
        self._place_name = name  # 维护(存放)一个地方名字

    @property
    def name(self):
        return self._place_name

    @abstractmethod
    def accept(self, visitor):  # 接待访问者的功能(抽象)
        pass


# 医院(具体类)
class Hospital(Place):

    # 接待访问者的功能(实现)
    def accept(self, visitor):
        if visitor.__class__ is Doctor:
            print(f"医院热情的接待他,因为他能帮助医院救人!")
        elif visitor.__class__ is Chef:
            print("医院快速的接待他,因为他来看病!")


# 餐馆(具体类)
class Restaurant(Place):

    # 接待访问者的功能(实现)
    def accept(self, visitor):
        if visitor.__class__ is Doctor:
            print(f"餐厅热情的接待他,因为他是顾客!")
        elif visitor.__class__ is Chef:
            print("餐厅快速的接待他,因为他要炒菜!")


# 访问者(抽象类)
class Visitor(ABC):

    @abstractmethod
    def visit(self, place):  # 访问一个地方(抽象)
        pass


# 医生(具体类)
class Doctor(Visitor):

    # 访问一个地方的能力
    def visit(self, place):
        print(f"医生尝试访问{place.name},", end="")
        place.accept(self)  # 这个地方是否接收当前对象的访问


# 厨师(具体类)
class Chef(Visitor):

    # 访问一个地方的能力
    def visit(self, place):
        print(f"厨师尝试访问{place.name},", end="")
        place.accept(self)  # 这个地方是否接收当前对象的访问


if __name__ == '__main__':
    # 实例化一个医院
    hospital = Hospital("蟒蛇市第一人民医院")

    # 实例化一个餐馆
    restaurant = Restaurant("幸福餐馆")

    # 实例化一个医生(访问者)
    doctor = Doctor()

    # 实例化一个厨师(访问者)
    chef = Chef()

    # ------------------ 访问 ------------------
    doctor.visit(hospital)  # 医生访问医院
    doctor.visit(restaurant)  # 医生访问餐馆
    chef.visit(hospital)  # 厨师访问医院
    chef.visit(restaurant)  # 厨师访问餐馆

"""
运行结果:
    医生尝试访问蟒蛇市第一人民医院,医院热情的接待他,因为他能帮助医院救人!
    医生尝试访问幸福餐馆,餐厅热情的接待他,因为他是顾客!
    厨师尝试访问蟒蛇市第一人民医院,医院快速的接待他,因为他来看病!
    厨师尝试访问幸福餐馆,餐厅快速的接待他,因为他要炒菜!
"""

中介者模式

from abc import ABC, abstractmethod


# 中介者(抽象类)
class Mediator(ABC):

    def __init__(self):
        self._hr = None
        self._student = None

    def set_hr(self, hr):
        self._hr = hr

    def set_student(self, student):
        self._student = student

    @abstractmethod
    def match(self):
        pass


# 角色(抽象类)
class Role(ABC):

    def __init__(self, name: str, offer: str, mediator: Mediator):
        self._name = name
        self._offer = offer
        self._mediator = mediator

    @property
    def name(self):
        return self._name

    @property
    def offer(self):
        return self._offer

    @abstractmethod
    def match(self, role):  # 和哪个人进行匹配?
        pass


# 学生(具体类)
class Student(Role):

    def match(self, role):
        self._mediator.set_student(self)  # 在"中介"里面,设置好自己的学生信息
        self._mediator.set_hr(role)  # 在"中介"里面,设置好自己想要应聘的HR
        self._mediator.match()  # 设置完毕后,运行"中介"的匹配功能


# 人事HR(具体类)
class HR(Role):

    def match(self, role):
        self._mediator.set_hr(self)  # 在"中介"里面,设置好自己的HR信息
        self._mediator.set_student(role)  # 在"中介"里面,设置好自己想要招聘的学生
        self._mediator.match()  # 设置完毕后,运行"中介"的匹配功能


# 猎聘App(具体类)
class LiePinApp(Mediator):

    def match(self):
        print("--------------- 欢迎使用猎聘App ---------------")
        print(f"HR:{self._hr.name}\t|\t想要招聘:{self._hr.offer}")
        print(f"学生:{self._student.name}\t|\t想要应聘:{self._student.offer}")
        if self._hr.offer == self._student.offer:
            print(">>> 配对成功")
        else:
            print(">>> 配对失败")
        print("---------------------------------------------", end="\n\n")


if __name__ == '__main__':
    # 实例化一个中介 ———— 猎聘App
    app = LiePinApp()

    # 实例化一个HR
    hr = HR("花儿姐", "软件工程师", app)

    # 实例化两个学生
    stu_1 = Student("小明", "软件工程师", app)
    stu_2 = Student("小王", "硬件工程师", app)

    # HR 通过 app 尝试匹配 stu_1
    hr.match(stu_1)
    hr.match(stu_2)

备忘录模式

"""
    备忘录模式:
        在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
        这样以后就可将该对象恢复到原先保存的状态。

    案例:
        比如我们打游戏时分,如果在打大BOSS之前存档,此时就需要将对应的游戏场景,任务信息,人物信息等等状态存储起来;
        当赢得大BOSS之后,覆盖之前的存档时,就将之前的存档丢弃,新建立一个存档,保存当前的状态信息;
        如果打输了,恢复存档,就将之前的存档信息读取出来,还原到打大BOSS之前的游戏场景,重新开始打大BOSS。
        这里面就是使用的备忘录模式。
        一个备忘录是一个对象,它存储另一个对象在某个瞬间的内部状态,而后者称为备忘录的原发器。
        当需要设置原发器的检查点时,取消操作机制会向原发器请求一个备忘录。
        原发器用描述当前状态的信息初始化该备忘录。
        只有原发器可以向备忘录中存取信息,备忘录中的信息对其他的对象是“不可见”的。
"""
from abc import ABC, abstractmethod


# 备忘录(具体类)
class Memorandum:

    def __init__(self, blood, attack, defense):
        self.__blood = blood
        self.__attack = attack
        self.__defense = defense

    @property
    def blood(self):
        return self.__blood

    @property
    def attack(self):
        return self.__attack

    @property
    def defense(self):
        return self.__defense


# 原发器:记录当前时刻的内部状态
class GameRole:

    # 创建游戏角色时,默认的血量
    def __init__(self, ):
        self.__blood = 100
        self.__attack = 100
        self.__defense = 100

    # 展示游戏角色的状态
    def show_state(self):
        print(f"当前角色:[生命力:{self.__blood}] [攻击力:{self.__attack}] [防御力:{self.__defense}]")

    # 让游戏角色进行战斗
    def fight(self):
        self.__blood -= 40
        self.__attack -= 16
        self.__defense -= 32
        print("遭受敌人攻击!生命力-40,攻击力-16,防御力-32...")

        if self.__blood <= 0:
            print("您已阵亡!")

    # 存档:保存当前的数据到备忘录对象中
    def save_state(self):
        print("存档成功!")
        return Memorandum(self.__blood, self.__attack, self.__defense)

    # 恢复存档:从备忘录对象里面获取所需的数据
    def recovery_state(self, memorandum: Memorandum):
        self.__blood = memorandum.blood
        self.__attack = memorandum.attack
        self.__defense = memorandum.defense
        print("恢复存档成功")


if __name__ == '__main__':
    # 创建一个游戏角色
    role = GameRole()

    # 查看当前"游戏角色"的状态
    role.show_state()

    # 玩游戏(去战斗)
    role.fight()

    # 存档
    record = role.save_state()

    # 继续玩游戏(去战斗)
    role.fight()
    role.fight()

    # 挑战Boss失败,就读档,恢复原来的状态
    role.recovery_state(record)

    # 继续玩游戏(去战斗)
    role.fight()

状态模式

from abc import ABC, abstractmethod


# 状态(抽象类)
class State(ABC):

    @abstractmethod
    def handle(self):
        pass


# "None"状态类(具体类)
class NoneState(State):

    def handle(self):
        return "没有上下文..."


# "Exist"状态类(具体类)
class ExistState(State):

    def handle(self):
        return "存在上下文..."


# 上下文(具体类)
class Context:

    def __init__(self, state: State):
        self.__state = state  # 存放一个状态对象

    # 请求上下文
    def request(self):
        if self.__state:
            print(f"内容:[{self.__state.handle()}]")

    # 改变状态
    def change_state(self, new_state):
        self.__state = new_state


if __name__ == '__main__':
    # 实例化两种状态
    none_state = NoneState()
    exist_state = ExistState()

    # 实例化一个上下文
    context = Context(none_state)

    # 请求内容
    context.request()

    # 切换为 noneState 状态后,再次请求内容
    context.change_state(exist_state)
    context.request()

迭代器模式

from abc import ABC, abstractmethod


# 简单迭代器(具体类)
class SimpleIterator:

    # 初始化操作
    def __init__(self, lst):
        self.__lst = lst  # 记录要被迭代的列表
        self.__index = 0  # 记录当前迭代位置的索引(下标),初始化时,设置为0

    # 重新定义 __iter__ ,防止用官方的 __iter__ 污染了自己要实现的迭代器
    def __iter__(self):
        return self

    # 重新定义 __next__,实现自定义功能
    def __next__(self):
        if self.__index < len(self.__lst):  # 索引(下标)合法
            element = self.__lst[self.__index]
            self.__index += 1
            return element
        else:  # 索引(下标)不合法
            raise StopIteration


if __name__ == '__main__':
    my_list = [5, 4, 3, 2, 1]
    my_iter = SimpleIterator(my_list)
    try:
        while True:
            print(next(my_iter))
    except StopIteration:
        pass

解释器模式

"""
    实现原理:
        原材料:
            1.表达式(计算规则):	a@b#c	(需要解释成a+b-c的运算过程和结果)
            2.数据对应关系(变量):
                var_map = {
                    "a": 30,
                    "b": 20,
                    "c": 25
                }

        产品:
            a@b#c ==》 变量解释器1 @ 变量解释器2 # 变量解释器3
                  ==》 栈 【 => 变量解释器1 => 变量解释器2 => 变量解释器3 => 】 与 【=> @符号对象 => #符号对象】
"""

from abc import ABC, abstractmethod


# 解释器(抽象类)
class Interpreter(ABC):

    @abstractmethod
    def parse(self, var_map: dict):  # 执行解析
        pass


# 变量解释器(具体类)
# 一个变量解释器对象只能解释一个变量字符
class VarInterpreter(Interpreter):

    def __init__(self, var: str):
        self.__var = var  # 用来记录待解析的变量字符

    def parse(self, var_map: dict) -> int:  # 函数返回值 int 类型
        return var_map[self.__var]


# 运算符解释器
# 1.抽象父类
class SymbolInterpreter(Interpreter):

    def __init__(self, left: VarInterpreter, right: VarInterpreter):
        self._left = left  # 用来记录"变量解释器对象"
        self._right = right  # 用来记录"变量解释器对象"

    @property
    def left(self):  # 提供接口,让外界可以读取
        return self._left

    @property
    def right(self):  # 提供接口,让外界可以读取
        return self._right

    @abstractmethod
    def parse(self, var_map: dict):
        pass


# 2.具体子类
# 2.1 加法解释器(具体类)
class AddInterpreter(SymbolInterpreter):

    def parse(self, var_map: dict) -> int:
        return self._left.parse(var_map) + self._right.parse(var_map)


# 2.2 减法解释器(具体类)
class SubInterpreter(SymbolInterpreter):

    def parse(self, var_map: dict) -> int:
        return self._left.parse(var_map) - self._right.parse(var_map)


# 封装一个解析者类,统一调用上面的接口
class Parser:

    def __init__(self, expression: str):
        self.__final_interpreter = None  # 存放(维护)一个最终解释器对象
        interpreter_stack = []  # 自定义栈,用来临时存放"解释器对象"的栈

        # 解析字符串 a@b#c
        i = 0
        while i < len(expression):
            # ---------------- 循环要做的事情 -----------------
            match expression[i]:
                case "@":  # 匹配到+这个符号,执行加法解释
                    # 从栈顶中读取解释器对象
                    left = interpreter_stack.pop()

                    # 从文法字符串中,构建解释器对象
                    right = VarInterpreter(expression[i + 1])

                    # 传入解释器对象,构建新的解释器对象,将其存入栈中
                    interpreter_stack.append(AddInterpreter(left, right))

                    # 因为 right 那里是提前构建了对象,所有我们需要跳过下一字符的匹配
                    i += 1

                case "#":  # 匹配到-这个符号,执行减法解释
                    # 从栈中取出解释器对象
                    left = interpreter_stack.pop()

                    # 从文法字符串中,构建解释器对象
                    right = VarInterpreter(expression[i + 1])

                    # 传入解释器对象,构建新的解释器对象,将其存入栈中
                    interpreter_stack.append(SubInterpreter(left, right))

                    # 因为 right 那里是提前构建了对象,所有我们需要跳过下一字符的匹配
                    i += 1

                case _:
                    interpreter_stack.append(VarInterpreter(expression[i]))
            # ---------------- 循环要做的事情 -----------------
            i += 1  # 循环自增

        # 保存最终解释对象
        if interpreter_stack:  # 如果栈不为空
            self.__final_interpreter = interpreter_stack.pop()  # 栈顶中保存的就是最终语法树的根

    # 执行解析
    def execute(self, var_map: dict) -> int:
        # self.__final_interpreter.parse(var_map) 的调用过程有点类似于递归,可以自己画图分析

        # 解析结果:
        res = -1 if (self.__final_interpreter is None) else self.__final_interpreter.parse(var_map)
        return res


if __name__ == '__main__':
    #  要解析的表达式
    expression = "a@b#c"

    # 符号与数据之间的映射关系————变量————法则
    var_map = {
        "a": 30,
        "b": 20,
        "c": 25
    }

    # 实例化一个解析者,解析上面的表达式
    parser = Parser(expression)

    # 执行解释
    res = parser.execute(var_map)  # 30@20#25 == 30+20-25 == 25
    print(res)

瑞萨芯片串口配置,基于RL78芯片的串口使用配置 在这里隆重给大家介绍瑞萨编辑器CS+ for CA 的自动生成代码功能,只需要配置几个参数,就可以得到你想要的串口配置了,我现在已经忘记怎么手动配置寄存器了,哈哈。选择设置,此时将端口设置成功接下来设置时钟,根据自己的芯片所需设置相应的时钟,自己芯片是什么时钟查看数据手册和原理图可以找到。瑞萨芯片的串口配置其实和ST芯片的串口配置差不多,只是ST芯片的中文数据手册比较多,就更好配置了,找到所需要的串口配置IO口,此时将UART0 配置为引脚P61和P62,瑞萨芯片的串口配置竟然要配置串口。 阅读详情

相关推荐

OpenCv案例(七): 基于OpenCvSharp计算图像的清晰度(自动对焦)

自动对焦,其实是对相机成像的清晰值得计算,若对焦不清晰,成像的清晰度低,视觉效果模糊。若是在工业检测行业,对焦不准确,可能会造成严重后果;对焦准确的图像,其清晰度高,对比度鲜明,层次明显。

qq_37835727的博客 7113

Python 设计模式(第2版) -- 第三部分(行为型模式)

再介绍下行为型设计模式。行为型模式,顾名思义,它主要关注的是对象的责任。它们用来处理对象之间的交互,以实现更大的功能。行为型模式建议:对象之间应该能够彼此交互,同时还应该是松散耦合的。观察者设计模式是最简单的行为型模式之一,所以,首先来看看观察者设计模式。

Talk is cheap, show the code. zhangsihui.pythonanywhere.com 1014

步进电机梯形加减速算法的实现

步进电机梯形加减速算法的实现

m0_69251699的博客 1318

Python版23种设计模式终极指南:原理+场景+实战代码全覆盖

本文完整实现了23种设计模式的Python代码示例,覆盖创建型结构型行为型三大类别。设计模式本质是代码设计经验的总结避免过度设计:优先使用简单直观的方案结合语言特性:如Python可利用装饰器语法简化实现关注场景匹配:如观察者模式适用于事件驱动系统保持灵活性:通过工厂模式隔离变化点。

燃灯工作室 2120

编译opencv4.2时出现undefined reference to `jpeg_default_qtables‘错误的解决方案

操作系统:kylinV10 opencv版本:4.2.0 在编译opencv4.2.0的版本时,出现undefined reference to `jpeg_default_qtables’的错误提示,导致openc编译中断,不能继续编译,所以这个错误必须解决。 解决方案 查看错误的名字,根据名字分析,很有可能是当前系统中没有安装jpeg第三方库,到 http://www.ijg.org/上下载最新的源码包 jpegsrc.v9e.tar.gz,按如下顺序开始编译安装: tar -xzvf jpegsr.

jndingxin的专栏 5105

21、时间触发以太网:通信、诊断、故障隔离与参数化详解

本文详细解析了时间触发以太网(TTEthernet)的核心机制,包括团检测算法、诊断服务、故障隔离策略、配置服务以及协议参数化等内容。TTEthernet是一种专为超高可靠性系统设计的网络技术,广泛应用于航空航天、工业自动化和汽车电子等领域。文章还探讨了其未来发展趋势,如技术创新与生态建设,为开发者、企业和研究机构提供了应用与发展的方向。

efc12345678的博客 110

设计模式看了又忘,忘了又看?

文章首发:设计模式看了又忘,忘了又看? 设计模式收藏这篇就够了 耗时了 5 个月,终于把设计模式一整个系列写完。其实设计模式这一系列文章网上已经有很多非常好、非常优秀的文章,为什么要写呢? 一方面是为了学得更扎实,印象中设计模式学习了 2 遍,记得牢的基本就那几个众所周知的,反思前面 2 次学习过程,缺少了思考的过程,没有把知识消化掉转化成自己的,就像动物一样,吃进去的东西没有消化只能排出。...

weixin_33947521的博客 456

EndNote导入文献出现带有大括号{}乱码的解决办法

进入word中的Endnote工具栏——Bibliography Preferences(位于Bibliography区块的右下角),就是那个输入杂志名的小三角形,在Temporary citation delimiters处修改变量的默认符号。将默认的大括号{}修改为文章中不回使用到的符号。原因:因为Endnote插入的参考文献在Word中的代码就是以大括号隔开的,当文章中出现了该符号,endnote就会自动比对Library中的书目,而此时endnote出现错误。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 4万+

【亲测免费】 探索《精通Python设计模式(第二版)》:构建高效代码的艺术

探索《精通Python设计模式(第二版)》:构建高效代码的艺术 在这个快速发展的编程世界里,掌握高效的编程技术和设计理念是提升软件质量的关键。GitCode上托管的《精通Python设计模式(第二版)》项目,正是一个旨在帮助开发者深入理解并应用Python设计模式的宝贵资源。 项目简介 该项目是一个完整的开源电子书,由Packt Publishing出版,作者是Amit Saha。它全面覆盖了23...

gitblog_00053的博客 427

端侧 AI 落地避坑指南(中):为什么 QAT 救不了精度?——对齐“融合后算子“的硬件物理约束

在上一篇文章中,我们深入探讨了量化的本质,并得出结论:QAT(量化感知训练)是保持精度的关键。明明做了 QAT,精度还是崩塌了!让我们看一个真实的案例:✅ 使用了✅ 配置了量化✅ 训练了 50 个 epoch,学习率降为原来的 1/10✅ 冻结了 BN 统计量FP32 模型:mAP = 0.85QAT 后 FP32:mAP = 0.84(正常)工具量化后:mAP = 0.68(崩塌!问题出在哪里?层融合(Layer Fusion)机制。

weixin_51988935的博客 55

PDD psnl_verification anti_content 生成顺序与环境校验说明

K不是明文 URL,而是从当前href再派生出来的一小段摘要值。页面 URL 变,K会跟着变但K不是直接肉眼可读的 URL 字串可以把它理解成“URL 的短摘要字段”。这一步是最容易被误解的地方。它吃进去的是压缩后的中间串不是直接吃环境字段它内部还带有长度预算 / 字符映射 / 位置处理逻辑所以最终看到的环境字段 bytes协议头deflate 压缩自定义编码多层叠加后的结果。先把字段总包做再把压缩结果转成raw再拼fTail最后走做字符级输出因此,当前看到的协议字段流。

码王吴彦祖的博客 68

23种设计模式Python版

目录创建型模式简单工厂模式工厂方法模式抽象工厂模式单例模式原型模式建造者模式结构型模式适配器模式桥接模式组合模式装饰器模式外观模式享元模式代理模式行为型模式职责链模式命令模式解释器模式迭代器模式中介者模式备忘录模式观察者模式状态模式策略模式模板方法模式访问者模式Reference 创建型模式 简单工厂模式 实现 from abc import abstractmethod, ABCMeta class Product(metaclass = ABCMeta): def __init__(se

ccnuacmhdu的博客 1623

基于语义分割的实时建图:HDMap动态更新

基于语义分割的实时建图:HDMap动态更新​ ,人工智能,计算机视觉,大模型,AI,本文围绕基于语义分割的实时建图技术在HDMap动态更新中的应用展开,介绍了语义分割基础、HDMap概述、相关实时建图技术、动态更新关键技术、系统性能评估指标、实际应用案例、面临的挑战与解决方案及未来发展趋势。阐述了该技术如何利用传感器数据和语义分割算法,解决传统HDMap构建与更新的弊端,分析了其在精度、实时性、鲁棒性等方面的表现,以及在自动驾驶和智能交通中的应用,还探讨了现存问题及未来优化方向。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 22万+

细说Python之观察者模式(行为型模式)

文章目录行为型模式介绍理解观察者设计模式现实世界中的观察者模式观察者模式的通知模式拉模型推模型松耦合与观察者模式观察者模式的优缺点问答环节: 行为型模式介绍 前面讲了创建型模式(单例模式)、结构型模式(门面模式),现在讲讲行为型模式(观察者模式)。 创建型模式的工作原理是基于对象的创建机制的。由于这些模式隔离了对象的创建细节,所以使得代码能够与要创建的对象的类型相互独立。结构型模式用于设计对象和类的结构,从而使它们可以相互协作以获得更大的结构。它们重点关注的是简化结构以及识别类和对象之间的关系。 行为型模

Apy 1195

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

设计模式Python版 桥接模式

介绍了GOF设计模式中的桥接模式,用Python实现桥接模式示例,以及桥接模式与适配器模式的联用。

分享、交流、合作 2519

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

设计模式Python版 享元模式

介绍了GOF设计模式中的享元模式,以及用Python实现享元模式的示例。

分享、交流、合作 1495

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

常用设计模式Python实现

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 代码查看:https://github.com/nonpricklycactus/Design-Pattern 一、设计模式分类 经典的《设计模式》一书归纳出23种设计模式,这23种模式又可...

nonpricklycactus的博客 6732

设计模式Python版 职责链模式

介绍了GOF设计模式中的职责链模式,用Python实现职责链模式示例,职责链模式分类。

分享、交流、合作 1319

设计模式Python版 迭代器模式

介绍了GOF设计模式中的迭代器模式,用Python实现迭代器模式示例,以及Python中的迭代器。

分享、交流、合作 1743

行为型模式对比:命令模式 vs 备忘录模式

在软件开发中,经常需要管理对象的行为与状态,比如执行操作、撤销操作、存储状态、恢复历史等。命令模式(Command Pattern)和 备忘录模式(Memento Pattern)都是用于管理对象行为或状态的行为型设计模式(Behavioral Design Patterns),但它们的作用和使用方式有很大不同。本文将从对行为和状态的控制、动作命令与状态存储、撤销与恢复的对比等方面,详细分析命令模式 vs 备忘录模式,帮助你理解它们的区别,并在实际开发中选择合适的模式。

840

设计模式Python版 代理模式

介绍了GOF设计模式中的代理模式,用Python实现代理模式示例。介绍了远程代理,虚拟代理和虚拟代理Python示例。

分享、交流、合作 1498

行为型设计模式的Python实践指南

行为型设计模式的Python实践指南 本文深入探讨了四种重要的行为型设计模式在Python中的实践应用:观察者模式、策略模式、模板方法模式和访问者模式。文章通过详细的代码示例、模式对比和实际应用场景分析,展示了如何在Python项目中优雅地实现这些模式。每种模式都涵盖了核心概念、实现原理、优势分析以及高级应用技巧,为开发者提供了全面的实践指南。 观察者模式:数据变更通知回调机制 观察者模式(Obs...

gitblog_00282的博客 606

设计模式Python版 原型模式

介绍了GOF设计模式中的原型模式,用Python实现原型模式示例,以及原型管理器。

分享、交流、合作 1847

设计模式Python版 单例模式

介绍了GOF单例模式,单例模式的Python示例,以及单例模式在Django框架的应用。

分享、交流、合作 3305

设计模式Python版 抽象工厂模式

介绍了GOF设计模式中的抽象工厂模式,抽象工厂模式的Python示例,以及Django框架中抽象工厂模式的应用。

分享、交流、合作 2451

设计模式Python版 组合模式

介绍了GOF设计模式中的组合模式,组合模式的实现方式,用Python实现组合模式示例,以及组合模式在Django中的应用。

分享、交流、合作 1285
上一篇: 结构型模式 (Python版)
下一篇: C++ 网络编程
code_stream
博客等级 码龄4年 1238粉丝 169原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值