Python实现单例模式的5种方法

yizhihongxing

下面是 Python 实现单例模式的 5 种方法的详细攻略。

什么是单例模式?

单例模式是一种常见的设计模式,它保证一个类只能创建一个实例,并提供一个全局访问该实例的方式。

Python 实现单例模式的 5 种方法

方法一:使用模块

Python 中的模块加载是线程安全的,因此将实例化代码放在模块级别的变量中,可以保证只有一个实例会被创建。

# singleton.py

class Singleton(object):
    def __new__(cls):
        if not hasattr(cls, '_instance'):
            cls._instance = super().__new__(cls)
        return cls._instance

这种方法需要将所有的单例类代码放在一个模块中,然后使用模块导入来获得单例对象。例如:

from singleton import Singleton

singleton = Singleton()

方法二:使用装饰器

使用装饰器将实例化代码封装在闭包中,然后用一个字典变量存储闭包对象和单例对象的对应关系,保证每个类只有一个实例对象。

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 MyClass(object):
    pass

方法三:使用元类

Python 中的类也是对象,因此可以使用元类来实现单例模式。元类是类的类,可以用来控制类的创建过程和行为。

class Singleton(type):
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super().__call__(*args, **kwargs)
        return cls._instance

class MyClass(metaclass=Singleton):
    pass

方法四:使用基类

将单例模式的实现封装到一个基类中,并在每个需要单例模式的类中继承该基类。

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

class MyClass(Singleton):
    pass

方法五:使用模板方法

使用模板方法模式将单例模式封装到一个基类中,并在每个子类中实现模板方法。

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

class MyClass(Singleton):
    def __init__(self, arg):
        self.arg = arg

    @classmethod
    def create_singleton(cls, arg):
        if not cls._instance:
            cls._instance = cls(arg)
        return cls._instance

这种方法需要子类实现一个静态方法或类方法来创建单例对象,例如:

my_object = MyClass.create_singleton('argument')

示例说明

下面我们来看两个关于单例模式的示例。

示例一:程序日志

在一个程序中,我们通常需要记录一些日志信息,而记录日志的类只需要一个实例即可。因此可以使用单例模式来实现日志记录类。

import logging

class SingletonLogger(object):
    _instance = None

    def __new__(cls):
        if not cls._instance:
            cls._instance = super().__new__(cls)
            cls._instance.logger = logging.getLogger(__name__)
        return cls._instance

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

在其他模块中使用 Logger 对象时,只需要导入 SingletonLogger 类并调用 log 方法即可。

from singleton_logger import SingletonLogger

logger = SingletonLogger()
logger.log('Logging message')

示例二:数据库连接池

在 Web 应用开发中,为了提高数据库访问效率,我们通常会使用连接池来管理数据库连接。连接池只需要一个实例即可,可以使用单例模式来实现。

import MySQLdb
from dbutils.pooled_db import PooledDB

class SingletonDatabase(object):
    _instance = None

    def __new__(cls):
        if not cls._instance:
            cls._instance = super().__new__(cls)
            cls._instance.pool = PooledDB(
                creator=MySQLdb,
                use_unicode=True,
                db='test',
                user='user',
                password='password',
                host='localhost',
                port=3306,
                charset='utf8mb4',
                maxconnections=100,
                blocking=True
            )
        return cls._instance

    def get_connection(self):
        return self.pool.connection()

    def close_connection(self, conn):
        conn.close()

在其他模块中使用数据库连接池时,只需要导入 SingletonDatabase 类并调用 get_connection 方法获取数据库连接即可。

from singleton_database import SingletonDatabase

db = SingletonDatabase()
conn = db.get_connection()
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
results = cursor.fetchall()
db.close_connection(conn)

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现单例模式的5种方法 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 解决pip安装tensorflow中出现的no module named tensorflow.python 问题方法

    当我们在使用pip安装tensorflow时,有时会遇到模块缺失的错误,例如: ImportError: No module named tensorflow.python. 这是因为我们在安装tensorflow的过程中,系统会默认选择tensorflow的CPU版本,而忽略了我们系统中是否存在GPU加速库CUDA和cudnn。因此我们需要手动指定安装te…

    python 2023年5月13日
    00
  • Python UnboundLocalError和NameError错误根源案例解析

    下面我来详细讲解一下“Python UnboundLocalError和NameError错误根源案例解析”的完整攻略。 1. UnboundLocalError错误 1.1 错误描述 当尝试在一个函数内部对一个局部变量进行赋值时,在函数定义之前没有声明该局部变量,就会引发UnboundLocalError错误。 1.2 错误示例 def my_functi…

    python 2023年5月13日
    00
  • python TK库简单应用(实时显示子进程输出)

    下面就来详细讲解一下“Python TK库简单应用(实时显示子进程输出)”的攻略。 什么是Python TK库 Python TK库是一个用于创建图形用户界面(GUI)的Python标准库,可以让用户通过可视化的方式与程序交互。它包括多个小部件(widgets),如按钮、标签、文本框等等,用户可以通过使用这些小部件来构建GUI界面。 如何安装Python T…

    python 2023年6月2日
    00
  • Python接口自动化判断元素原理解析

    Python 接口自动化判断元素原理解析 在 Python 接口自动化测试中,判断元素是否存在是一个非常重要和基础的操作。本文将介绍 Python 接口自动化测试中的判断元素原理解析,包括常用的 Http 请求响应代码、Json 响应数据解析、字符串匹配以及正则表达式匹配等。 通过 Http 响应代码判断元素存在 在接口请求后,如果响应代码是 200,那么请…

    python 2023年5月19日
    00
  • python通过文件头判断文件类型

    下面是Python通过文件头判断文件类型的完整实例教程。 1. 什么是文件头 文件头(File Header)指的是文件的开头几个字节,包含了文件的一些基本信息。不同类型的文件,在文件头中包含的信息不同,因此可以通过读取文件头来判断文件的类型。 2. 用Python判断文件类型的方法 Python中可以通过读取文件头来判断文件类型,具体方法如下: impor…

    python 2023年5月13日
    00
  • Python入门必须知道的11个知识点

    Python入门必须知道的11个知识点 Python是一种简单易学、功能强大的编程语言,已经得到了广泛的应用。下面是入门Python必须知道的11个知识点,包括变量、数据类型、运算符、条件语句、循环语句、函数、模块、I/O操作、异常处理、面向对象编程和常用的第三方库。 变量 变量是用来存储数据的容器,Python中的变量不需要事先声明数据类型,可以直接赋值。…

    python 2023年6月5日
    00
  • Python 类的魔法属性用法实例分析

    Python 类的魔法属性用法实例分析。 什么是魔法属性 在Python中,我们经常会看到以双下划线开头和结尾的属性名,例如__init__、__str__等,这些属性也被称为魔法属性(Magic Method),因为它们有很强大的魔力,可以实现许多特殊的行为。 魔法属性的作用是用于定义类的特殊行为,我们可以在自定义类中重写这些属性,从而实现自定义的特殊行为…

    python 2023年6月7日
    00
  • Python代码实现KNN算法

    Python代码实现KNN算法 KNN(K-Nearest Neighbors)是一种常用的分类算法,它的基本思想是:对于一个未知样本,找与最近的K个已知样本,然后根据这K个样本的类别进行分类。Python中,可以使用scikit-learn库实现KNN分类算法。本文将详细讲解Python实现KNN分类算法的完整攻略,包括算法原理、Python实现过程和示例…

    python 2023年5月13日
    00
合作推广
合作推广
分享本页
返回顶部