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.')

输出:

相关推荐
逆境不可逃2 小时前
【从零入门23种设计模式16】行为型之迭代器模式
java·开发语言·数据结构·算法·设计模式·职场和发展·迭代器模式
李昊哲小课2 小时前
Python OS模块详细教程
服务器·人工智能·python·microsoft·机器学习
JTCC2 小时前
Java 设计模式西游篇 - 第七回:责任链模式过难关 通关文牒层层批
java·设计模式·责任链模式
每日IO2 小时前
AI“重构”生活 —— Mind+ V2 模型训练挑战赛
人工智能·python·mind+·开源硬件·模型训练·二哈识图·行空板
JTCC2 小时前
Java 设计模式西游篇 - 第九回:外观模式简化繁 如来神掌一指定
java·设计模式·外观模式
Ronin3052 小时前
【Qt常用控件】按钮类控件
开发语言·qt·常用控件·按钮类控件
慧都小项2 小时前
JAVA开发工具IntelliJ IDEA v2026更新前瞻:更优的交互视觉,编程体验升级
java·开发语言·intellij-idea
wsad05322 小时前
在Windows上创建Python虚拟环境并在PyCharm中使用
windows·python·pycharm
geovindu2 小时前
python: Prototype Pattern
python·设计模式·原型模式