python: Singleton Pattern

在珠宝行业中,有很多天然适合单例模式的场景:比如「珠宝库存管理中心」(全公司只有一个库存总仓)、「珠宝鉴定证书生成器」(全系统只有一个证书编号生成器)、「会员积分结算中心」等。这些场景的核心特征是:全局唯一、集中管控、数据一致。

python 复制代码
# encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:单例模式 Singleton Pattern
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2024.3.6 python 3.11
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/3/7 15:48
# User      :  geovindu
# Product   : PyCharm
# Project   : pydesginpattern
# File      : DuJewelry.py
from dataclasses import dataclass  # 使用dataclass简化实体类定义
from datetime import date
 
# -------------1. 先定义珠宝实体类(Jewelry)
 
@dataclass
class DuJewelry:
    """
    珠宝实体类,包含珠宝行业核心属性
    """
    sku:str
    """
    唯一编号(如:G20260307001)
    """
    category:str
    """
    品类:戒指/项链/手镯
    """
    material :str
    """
    材质:黄金/钻石/翡翠
    """
    weight :float
    """
    克重(黄金)/克拉(钻石)
    """
    price:float
    """
    单价(元)
    """
    stock:int
    """
     初始库存
    """
 
    def __str__(self):
        """
        自定义打印格式,让珠宝信息更易读"
        :return:
        """
        return f"珠宝[{self.sku}]:{self.category} | {self.material} | {self.weight}({'' if '钻石' in self.material else '克'}克拉) | 单价{self.price}元 | 库存{self.stock}件"
python 复制代码
# encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:单例模式 Singleton Pattern
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2024.3.6 python 3.11
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/3/7 15:53
# User      :  geovindu
# Product   : PyCharm
# Project   : pydesginpattern
# File      : JewelryInventoryCenter.py
 
from Model.DuJewelry import DuJewelry
# ----2. 实现单例模式的库存管理中心
 
 
def singleton(cls):
    """
    单例装饰器:确保类只有一个实例
    :param cls:
    :return:
    """
    instances = {}
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper
 
@singleton
class JewelryInventoryCenter:
    """
    珠宝库存管理中心(单例类):全公司唯一的库存管控中心
    """
    def __init__(self):
        """
        初始化
        """
        # 初始化库存字典:key=珠宝sku,value=Jewelry对象
        self.inventory = {}
        print("✅ 珠宝库存管理中心已初始化(全局唯一实例)")
 
    def add_jewelry(self, jewelry: DuJewelry):
        """
        入库:添加/更新珠宝库存
        :param jewelry:
        :return:
        """
        if jewelry.sku in self.inventory:
            # 已有该珠宝,累加库存
            self.inventory[jewelry.sku].stock += jewelry.stock
            print(f"📦 珠宝[{jewelry.sku}]库存更新:新增{jewelry.stock}件,当前库存{self.inventory[jewelry.sku].stock}件")
        else:
            # 新珠宝,加入库存
            self.inventory[jewelry.sku] = jewelry
            print(f"📥 珠宝[{jewelry.sku}]入库成功,初始库存{jewelry.stock}件")
 
    def remove_jewelry(self, sku: str, quantity: int):
        """
        出库:扣减珠宝库存(需校验库存充足)
        :param sku:
        :param quantity:
        :return:
        """
        if sku not in self.inventory:
            raise ValueError(f"❌ 珠宝[{sku}]不存在,无法出库")
        jewelry = self.inventory[sku]
        if jewelry.stock < quantity:
            raise ValueError(f"❌ 珠宝[{sku}]库存不足(当前{jewelry.stock}件,需出库{quantity}件)")
        jewelry.stock -= quantity
        print(f"📤 珠宝[{sku}]出库{quantity}件,剩余库存{jewelry.stock}件")
 
    def query_stock(self, sku: str) -> DuJewelry:
        """
        查询库存:根据sku返回珠宝信息
        :param sku:
        :return:
        """
        if sku not in self.inventory:
            raise ValueError(f"❌ 未查询到珠宝[{sku}]的库存信息")
        return self.inventory[sku]
 
    def get_all_inventory(self):
        """
        查询全量库存
        :return:
        """
        if not self.inventory:
            print("📜 当前库存为空")
            return
        print("\n📜 全公司珠宝库存清单:")
        for jewelry in self.inventory.values():
            print(jewelry)
python 复制代码
# encoding: utf-8
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:单例模式 Singleton Pattern
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2024.3.6 python 3.11
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/3/7 15:56
# User      :  geovindu
# Product   : PyCharm
# Project   : pydesginpattern
# File      : SingletonBll.py
 
from SingletonPattern.JewelryInventoryCenter import JewelryInventoryCenter
from Model.DuJewelry import DuJewelry
# -----3. 业务流程演示(调用示例)
 
class SingletonBll(object):
    """
    单例模式 Singleton Pattern
    """
    def demo(self):
        """
        单例模式 Singleton Pattern
        :return:
        """
        # 1. 创建库存管理中心(第一次调用,初始化实例)
        inventory_center1 = JewelryInventoryCenter()
        # 2. 再次创建库存管理中心(返回已有的唯一实例)
        inventory_center2 = JewelryInventoryCenter()
 
        # 验证单例:两个变量指向同一个实例
        print(f"\n🔍 验证单例:inventory_center1 == inventory_center2 → {inventory_center1 is inventory_center2}")
 
        # 3. 定义珠宝实体(模拟采购的珠宝)
        gold_ring = DuJewelry(
            sku="G20260307001",
            category="戒指",
            material="足金999",
            weight=3.5,  # 3.5克
            price=680,  # 680元/克
            stock=10  # 采购10件入库
        )
        diamond_necklace = DuJewelry(
            sku="D20260307001",
            category="项链",
            material="钻石",
            weight=0.5,  # 0.5克拉
            price=12000,  # 12000元/克拉
            stock=5  # 采购5件入库
        )
 
        # 4. 入库操作
        inventory_center1.add_jewelry(gold_ring)
        inventory_center1.add_jewelry(diamond_necklace)
        # 对已有珠宝追加库存(比如再次采购)
        gold_ring_add = DuJewelry(sku="G20260307001", category="戒指", material="足金999", weight=3.5, price=680, stock=5)
        inventory_center1.add_jewelry(gold_ring_add)
 
        # 5. 查询单个珠宝库存
        print("\n🔍 查询黄金戒指库存:")
        print(inventory_center1.query_stock("G20260307001"))
 
        # 6. 出库操作(门店提货)
        try:
            inventory_center1.remove_jewelry("G20260307001", 3)  # 出库3件黄金戒指
            inventory_center1.remove_jewelry("D20260307001", 1)  # 出库1件钻石项链
        except ValueError as e:
            print(e)
 
        # 7. 查看全量库存
        inventory_center1.get_all_inventory()
 
        # 8. 尝试出库超出库存的数量(模拟异常场景)
        try:
            inventory_center1.remove_jewelry("D20260307001", 10)
        except ValueError as e:
            print(f"\n⚠️ 异常提示:{e}")

调用:

python 复制代码
# encoding: utf-8
# 版权所有 2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述: 设计模式 Design Patterns
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : PyCharm 2023.1 python 3.11
# OS        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  oracle 21c Neo4j
# Datetime  : 2026/2/18 20:58
# User      : geovindu
# Product   : PyCharm
# Project   : pydesginpattern
# File      : main.py
# explain   : 学习
 
import Controller.CheckPatterns
 
 
def select_design_pattern() -> tuple[int, Controller.CheckPatterns.DesignPattern | None]:
    """
    返回 (序列号, 选中的枚举对象),退出则返回 (0, None)
    :return:
    """
    print("\n=== 方式3:用户选择展示 ===")
    print("可选设计模式(输入0或q退出):")
    for idx, pattern in enumerate(Controller.CheckPatterns.DesignPattern, 1):
        print(f"{idx}. {pattern._name_to_cn(pattern.name)}({pattern.name})")
    print("0. 退出")
 
    while True:
        user_input = input("\n请输入序号选择要展示的设计模式(输入0/q退出):").strip()
        if user_input in ("0", "q", "Q"):
            print("👋 退出选择流程")
            return (0, None)
 
        try:
            choice = int(user_input)
            if 1 <= choice <= len(Controller.CheckPatterns.DesignPattern):
                selected_pattern = list(Controller.CheckPatterns.DesignPattern)[choice - 1]
                print(f"✅ 你选择了序号:{choice}(对应{selected_pattern._name_to_cn(selected_pattern.name)})")
                return (choice, selected_pattern)  # 返回(序列号, 枚举对象)
            else:
                print(f"❌ 输入无效!请输入1-{len(Controller.CheckPatterns.DesignPattern)}之间的数字,或0/q退出")
        except ValueError:
            print("❌ 输入无效!请输入数字序号,或0/q退出")
 
def ask_continue() -> bool:
    """
    询问用户是否继续选择,返回True(继续)/False(退出)
    """
    while True:
        user_choice = input("\n是否继续选择其他设计模式?(y/n):").strip().lower()
        if user_choice == "y":
            return True
        elif user_choice == "n":
            print("👋 感谢使用,程序结束!")
            return False
        else:
            print("❌ 输入无效!请输入 y(继续)或 n(退出)")
 
 
if __name__ == '__main__':
 
    # 方式1:用户输入选择展示(交互版)
    '''
    print("\n=== 方式1:用户选择展示 ===")
    print("可选设计模式:")
    for idx, pattern in enumerate( bll.CheckPatterns.DesignPattern, 1):
        print(f"{idx}. {pattern._name_to_cn(pattern.name)}({pattern.name})")
 
    try:
        choice = int(input("\n请输入序号选择要展示的设计模式:"))
        selected_pattern = list( bll.CheckPatterns.DesignPattern)[choice - 1]
        selected_pattern.show_example()
    except (ValueError, IndexError):
        print("❌ 输入无效,请输入正确的序号!")
    '''
    # 2
 
    print("🎉 设计模式示例展示程序")
    while True:
        # 1. 选择设计模式
        selected_num, selected_pattern = select_design_pattern()
 
        # 2. 判断是否直接退出(输入0/q)
        if selected_num == 0:
            print("👋 程序结束!")
            break
 
        # 3. 执行选中的示例
        selected_pattern.show_example()
        print(f"\n📌 本次选择的序列号是:{selected_num}")
 
        # 4. 询问是否继续
        if not ask_continue():
            break  # 用户选择不继续,终止循环
 
    print('hi,welcome geovindu.')

输出:

相关推荐
源码之家6 分钟前
大数据毕业设计汽车推荐系统 Django框架 可视化 协同过滤算法 数据分析 大数据 机器学习(建议收藏)✅
大数据·python·算法·django·汽车·课程设计·美食
HealthScience7 分钟前
COM Surrogate的dllhost.exe高占用(磁盘)解决
python
羊小猪~~11 分钟前
【QT】-- 模型与视图简介
开发语言·数据库·c++·后端·qt·前端框架·个人开发
站大爷IP11 分钟前
用 Python 30 分钟做出自己的记事本
python
曲幽12 分钟前
FastAPI里玩转Redis和数据库的正确姿势,别让异步任务把你坑哭了!
redis·python·mysql·fastapi·web·celery·sqlalchemy·task·backgroundtask
叶微信12 分钟前
Qt相关面试题
开发语言·qt
淼淼爱喝水16 分钟前
OpenEuler 系统下 Ansible 环境部署与连通性测试完整步骤
linux·开发语言·php·openeuler
未知鱼18 分钟前
Python安全开发之简易csrf检测工具
python·安全·csrf
何政@25 分钟前
Agent Skills 完全指南:从概念到自定义实践
人工智能·python·大模型·claw·404 not found 罗
七夜zippoe27 分钟前
OpenClaw 多渠道统一管理:构建全平台智能消息中枢
开发语言·microsoft·github·多渠道·openclaw