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 单例模式的作用

  • 资源共享: 通过单例模式,我们确保了日志记录器在整个应用程序中只有一个实例,避免了资源的浪费。
  • 集中管理: 所有日志记录都通过同一个实例进行管理,便于维护和查看。
  • 一致性: 由于所有模块都使用同一个日志记录器,日志输出的一致性得以保证,便于调试和分析。
相关推荐
m0_7482359520 分钟前
Python大数据可视化:基于Python的王者荣耀战队的数据分析系统设计与实现_flask+hadoop+spider
hadoop·python·flask
Dyan_csdn31 分钟前
【Python项目】基于Python的Web漏洞挖掘系统
网络·python·安全·web安全
Minner-Scrapy36 分钟前
DApp 开发入门指南
开发语言·python·web app
&小刘要学习&1 小时前
anaconda不显示jupyter了?
python·jupyter
jerry-891 小时前
jupyterhub_config配置文件内容
python
快下雨了L1 小时前
C++面试笔记(持续更新...)
笔记
奔跑吧邓邓子1 小时前
【Python爬虫(36)】深挖多进程爬虫性能优化:从通信到负载均衡
开发语言·爬虫·python·性能优化·负载均衡·多进程
学长学姐我该怎么办2 小时前
年前集训总结python
python
量化投资技术2 小时前
【量化科普】Sharpe Ratio,夏普比率
python·量化交易·量化·量化投资·qmt·miniqmt
yanglamei19622 小时前
基于Python+Django+Vue的旅游景区推荐系统系统设计与实现源代码+数据库+使用说明
vue.js·python·django