Python 单例模式笔记

一、什么是单例模式

单例模式(Singleton Pattern)是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点来获取该实例。这种模式通常用于需要控制对某些资源的访问的场景,例如数据库连接、配置管理等。

二、单例模式的特点

  1. 唯一性: 单例模式确保一个类只有一个实例。无论在程序的哪个地方请求该类的实例,返回的都是同一个对象。

  2. 全局访问: 提供一个全局访问点,允许其他对象或类访问该实例。

  3. 延迟初始化: 单例模式通常会在第一次访问时创建实例,而不是在程序启动时就创建。

三、单例模式的实现

3.1 使用类变量

python 复制代码
class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance

# 使用示例
singleton1 = Singleton()
singleton2 = Singleton()

print(singleton1 is singleton2)  # 输出: True,两个变量指向同一个实例

3.2 使用装饰器

还可以使用装饰器来实现单例模式:

python 复制代码
def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class Singleton:
    pass

# 使用示例
singleton1 = Singleton()
singleton2 = Singleton()

print(singleton1 is singleton2)  # 输出: True

3.3 使用模块

在 Python 中,模块本身就是单例的。可以将需要共享的状态或数据放在一个模块中,其他模块可以直接导入并使用。

python 复制代码
# my_module.py
shared_variable = 0

def increment():
    global shared_variable
    shared_variable += 1
python 复制代码
# main.py
import my_module

my_module.increment()
print(my_module.shared_variable)  # 输出: 1

四、单例模式的应用场景

  • 配置管理: 在应用程序中,通常只需要一个配置管理器来读取和存储配置数据。
  • 日志记录: 只需一个日志记录器实例来处理所有的日志记录请求。
  • 数据库连接: 在应用程序中,通常只需要一个数据库连接池实例来管理数据库连接。

五、Python 单例模式在开发中的作用

在软件开发中,单例模式可以帮助我们管理共享资源,确保在整个应用程序中只有一个实例存在。接下来,将通过一个稍微复杂一点的程序项目来说明单例模式的作用。

假设我们正在开发一个简单的日志记录系统,该系统需要在整个应用程序中共享一个日志记录器实例。我们希望确保所有模块都使用同一个日志记录器,以便集中管理日志输出。

5.1 定义日志记录器类

我们将创建一个 Logger 类,使用单例模式确保只有一个日志记录器实例。该类将提供记录日志的功能,并将日志输出到文件中。

python 复制代码
import os
import logging

class Logger:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(Logger, cls).__new__(cls)
            cls._instance._initialize_logger()
        return cls._instance

    def _initialize_logger(self):
        log_dir = 'logs'
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)

        log_file = os.path.join(log_dir, 'app.log')
        self.logger = logging.getLogger('AppLogger')
        self.logger.setLevel(logging.DEBUG)

        file_handler = logging.FileHandler(log_file)
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
        file_handler.setFormatter(formatter)
        self.logger.addHandler(file_handler)

    def log(self, message):
        self.logger.debug(message)

# 使用示例
logger1 = Logger()
logger1.log("This is a log message from logger1.")

logger2 = Logger()
logger2.log("This is a log message from logger2.")

print(logger1 is logger2)  # 输出: True,两个变量指向同一个实例

5.2 使用日志记录器

在项目的其他模块中,我们可以直接使用 Logger 类来记录日志,而不需要担心创建多个实例。

python 复制代码
# module_a.py
from logger import Logger

def function_a():
    logger = Logger()
    logger.log("Function A is called.")

# module_b.py
from logger import Logger

def function_b():
    logger = Logger()
    logger.log("Function B is called.")

# main.py
from module_a import function_a
from module_b import function_b

function_a()
function_b()

5.3 运行程序

当您运行 main.py 时,您将看到所有日志消息都被写入同一个日志文件 app.log 中。无论是从 function_a 还是 function_b 记录的日志,都会集中在同一个日志记录器实例中。

5.4 单例模式的作用

  • 资源共享: 通过单例模式,我们确保了日志记录器在整个应用程序中只有一个实例,避免了资源的浪费。
  • 集中管理: 所有日志记录都通过同一个实例进行管理,便于维护和查看。
  • 一致性: 由于所有模块都使用同一个日志记录器,日志输出的一致性得以保证,便于调试和分析。
相关推荐
Olrookie8 分钟前
若依前后端分离版学习笔记(十九)——导入,导出实现流程及图片,文件组件
前端·vue.js·笔记
初圣魔门首席弟子9 分钟前
C++ STL string(字符串)学习笔记
c++·笔记·学习
程序员晚枫19 分钟前
Python 3.14正式发布!这5大新特性太炸裂了
python
CS_Zero21 分钟前
【开发工具】Windows10&11远程Ubuntu18及以上桌面
笔记·ubuntu
先做个垃圾出来………29 分钟前
SortedList
python
这里有鱼汤31 分钟前
从DeepSeek到Kronos,3个原因告诉你:Kronos如何颠覆传统量化预测
后端·python·aigc
晓宜40 分钟前
Java25 新特性介绍
java·python·算法
iconball1 小时前
个人用云计算学习笔记 --18(NFS 服务器、iSCSI 服务器)
linux·运维·笔记·学习·云计算
深栈1 小时前
机器学习:决策树
人工智能·python·决策树·机器学习·sklearn
MediaTea1 小时前
Python:匿名函数 lambda
开发语言·python