Python实现单例模式

这篇具有很好参考价值的文章主要介绍了Python实现单例模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、介绍

单例模式是一种常见的设计模式,它保证一个类只能被实例化一次,并提供了一个全局访问点来获取这个唯一的实例。在Python中,可以通过使用装饰器、元类或模块等方式实现单例模式。

二、Python实现单例模式的6种方法

1、使用模块实现单例

class Singleton(object):
    def foo(self):
        pass
singleton = Singleton()
from mysingleton import singleton
a = singleton
b = singleton
print(id(a))
print(id(b))

Python实现单例模式,python,单例模式,python  

2、通过装饰器实现单例

def singleeton_func(cls):
    instance={}
    def _singleton(*args, **kwargs):
        if cls not in instance:
            instance[cls] = cls(*args, **kwargs)
        return instance[cls]
    return _singleton

@singleeton_func
class Phone(object):
    def phone_id(self):
        return id(self)

if __name__ == '__main__':
    p1 = Phone()
    p2 = Phone()
    print(p1.phone_id())
    print(p2.phone_id())

Python实现单例模式,python,单例模式,python

在装饰器的内函数中,判断字典是否已经有键值对。如果没有,则添加一个类和类实例的键值对,如果有,则不添加。最后返回字典中的类实例,可以保证每次返回的都是同一个实例。要使用这个单例装饰器,只要将其装饰到需要实现单例的类上即可。

3、使用实例化方式实现单例

class SingletonInstance(object):
    def __call__(self, *args, **kwargs):
        return self
if __name__ == '__main__':
    SingletonInstance = SingletonInstance()
    s1 = SingletonInstance()
    s2 = SingletonInstance()
    print(id(s1))
    print(id(s2))

Python实现单例模式,python,单例模式,python

 在类中,先重写类的 __call__ 方法,在 __call__ 方法中返回自己。先实例化一个类的对象,后面所有需要使用这个类的地方,都调用这个实例对象。这样,每次调用的都是同一个实例,所以也能实现单例。

4、使用类装饰器实现单例

class SingletonDecorator(object):
    _instance = None
    def __init__(self, cls):
        self._cls = cls

    def __call__(self, *args, **kwargs):
        if self._instance is None:
            self._instance = self._cls(*args, **kwargs)
        return self._instance

@SingletonDecorator
class Phone(object):
    def phone_id(self):
        return id(self)

if __name__ == '__main__':
    p1 = Phone()
    p2 = Phone()
    print(p1.phone_id())
    print(p2.phone_id())

Python实现单例模式,python,单例模式,python

_var:命名约定,仅供内部使用。通常不会由Python解释器强制执行。(私有变量)
var_:按约定使用以避免与Python关键字的命名冲突。
__var:当在类上下文中使用时,触发”名称修饰“。由Python解释器强制执行。
__var__:表示Python语言定义的特殊方法。避免在你自己的属性中使用这种命名方案。

使用装饰器实现单例,因为装饰器除了可以使用闭包实现,还可以使用类实现,所以也可以使用类装饰器来实现单例。通过重写类的 __call__ 方法实现类装饰器,在 __call__ 方法中判断当前是否有类实例,没有才会创建,从而实现单例。

5、重写类的__new__方法实现单例

python中的super()详解参考python中的super调用父类方法

class SingletonClass(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            # cls._instance = super(SingletonClass, cls).__new__(cls)  # python2.x中,super()函数的使用语法格式
            cls._instance = super().__new__(cls)  # python3.x中,super()函数的使用语法格式
        return cls._instance

    _is_init = False
    def __init__(self):
        if self._is_init is False:
            print('-*-')
            self._is_init = True

if __name__ == '__main__':
    s1 = SingletonClass()
    s2 = SingletonClass()
    print(id(s1))
    print(id(s2))

Python实现单例模式,python,单例模式,python  

 在Python类中,每次实例化一个类对象时,都会自动先执行__new__方法和__init__方法。

__new__方法先在内存中为实例对象申请空间,然后__init__方法初始化实例对象。因为__init__方法是在new执行完成后自动执行的,每次实例类的对象时都会执行__init__方法,所以也要对__init__方法进行重写,只有第一次实例化类对象时才执行初始化操作。

通过重写__new__方法,如果这个类没有实例对象,则执行__new__,有则返回已有的实例,从而实现单例。

6、通过元类(metaclass)实现单例

元类详解参考Python中的元类

class SingletonMeta(type, object):
    def __init__(self, *args, **kwargs):
        self._instance = None
        super().__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if self._instance is None:
            self._instance = super().__call__(*args, **kwargs)
        return self._instance

class Phone(object, metaclass=SingletonMeta):
    def phone_id(self):
        return id(self)

if __name__ == '__main__':
    p1 = Phone()
    p2 = Phone()
    print(p1.phone_id())
    print(p2.phone_id())

Python实现单例模式,python,单例模式,python

上述代码中,我们定义了一个名为SingletonMeta的元类。在元类的__call__方法中,我们首先判断该类是否已经存在于instances字典中,如果不存在,则创建一个新的实例并将其添加到instances字典中,否则返回已有的实例。 

 在python中,元类是创建类的类,是创建类的工厂,所有类的元类都是type类,所有类都是type类的实例对象。
 如果自定义一个元类,在元类中重写__call__方法,判断当前是否有实例,没有实例才创建,有则不创建。对需要实现单例的类,指定类的元类是我们自定义的元类,从而实现单例。(不推荐使用此方法)

三、单例模式应用场景

单例模式适用于需要确保一个类只有一个实例对象,并且该对象需要被全局访问的情况。
(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如日志文件、应用配置。
(2)控制资源的情况下,方便资源之间的互相通信。如线程池等。

实例--单例模式控制数据库连接池对象:

 假设我们正在开发一个多线程的应用程序,其中包含一个数据库连接池对象。为了避免在多个地方重复创建数据库连接池对象,我们可以使用单例模式来确保该对象只会被创建一次,并且在多个线程之间共享一个对象。

import threading
class DatabaseConnectionPool:
    instance = None
    lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if cls.instance is None:
            with cls.lock:
                if cls.instance is None:
                    cls.instance = super().__new__(cls)
        return cls.instance

    def __init__(self):
        self.connections = []


    def add_connection(self, connection):
        self.connections.append(connection)

    def get_connection(self):
        return self.connections


# 使用示例
pool = DatabaseConnectionPool()
pool.add_connection("connection1")
pool.add_connection("connection2")

def worker(i):
    pool = DatabaseConnectionPool() # 多个线程共享同一个对象
    pool.add_connection("connection"+str(i+1))
    connection = pool.get_connection()
    print(f'Thread-{threading.get_ident()} got connection:{connection}')

if __name__ == '__main__':
    for i in range(4):
        t = threading.Thread(target=worker(i))
        t.start()

Python实现单例模式,python,单例模式,python

上述代码中,我们首先定义了一个名为 DatabaseConnectionPool 的单例类,它维护了一个连接池列表 connections,通过 add_connection 和 get_connection 方法来添加和获取连接。使用 __new__ 方法来创建单例对象,确保在多个线程之间只有一个实例,同时使用锁来保证线程安全。
然后,我们在多个线程中使用同一个连接池对象,并通过 get_connection 方法来获取连接。由于所有的线程都共享同一个连接池对象,因此在获取连接时不会出现资源浪费和重复创建对象等问题。文章来源地址https://www.toymoban.com/news/detail-608914.html

到了这里,关于Python实现单例模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python入门【​编辑、组合、设计模式_工厂模式实现 、设计模式_单例模式实现、工厂和单例模式结合、异常是什么?异常的解决思路 】(十七)

    👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀 🔥如果感觉博主的文章还不错的

    2024年02月14日
    浏览(44)
  • Python 实现单例模式的几种方式以及存在的问题

    Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。 直接在其他文件中导入此文件中的对象,这个对象即是单例模式的对象 先执行了类的__new__方法(我们没写时,默认调用ob

    2024年01月22日
    浏览(48)
  • 【单例设计模式原理详解】Java/JS/Go/Python/TS不同语言实现

    单例模式(Singleton Pattern)属于创建型设计模式,这种模式只创建一个单一的类,保证一个类只有一个实例,并提供一个访问该实例的全局节点。 当您想控制实例数目,节省系统资源,并不想混用的时候,可以使用单例模式。单例有很多种实现方式,主要分为懒汉和饿汉模式

    2023年04月27日
    浏览(93)
  • 5.python设计模式【单例模式】

    内容:保证一个类只有一个实例,并提供一个访问它的全局访问点 角色: 单例(Singleton) UML图 举个例子: 需求:一个类只能实例化一个对象,不能实例化多个对象 输出结果 20 20 139718467807696 139718467807696 说明是同一个对象 优点: 对唯一实例的受控访问 单例相当于全局变量

    2024年02月15日
    浏览(42)
  • python单例模式

    设计模式:单例模式(Singleton Pattern)。单例模式确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。 在这个例子中: cls指的是类Singleton本身。 super(). new (cls)调用父类(在这个例子中是object类)的__new__方法来创建类Singleton的一个新实例。这是因为__new__是在创

    2024年02月04日
    浏览(45)
  • python 单例模式

    单例模式是一种设计模式,目的是确保一个类只有一个实例,并提供一个全局访问点来获取该实例。 有些类只需要一个全局唯一的实例,例如数据库连接池、线程池、日志记录器等。使用单例模式可以确保这些类只有一个实例存在,从而避免了资源的浪费和不一致的状态。

    2024年02月15日
    浏览(46)
  • Python单例模式介绍、使用

    概念:单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供访问该实例的全局访问点。 功能:单例模式的主要功能是确保在应用程序中只有一个实例存在。 优势: 节省系统资源:由于只有一个实例存在,因此系统的资源占用会比较小。 更好的控制全局变量

    2024年02月16日
    浏览(35)
  • Python 面向对象之单例模式

    单例模式是一种设计模式,其核心思想是确保一个类只有一个实例,并提供一个全局访问点。 单例模式通常用于管理共享的资源,例如配置信息、数据库连接、线程池等。 关键点在于如何判断这个类是否已经实例化 通过模块导入:借助模块的底层导入原理 通过元类实现:元

    2024年01月25日
    浏览(61)
  • python 单例模式,装饰类,装饰函数

    知乎 python 实现单例模式的两种方式 stack overflow 装饰函数 vs 装饰类 medium Do we even need a class to realize singleton? 单例模式大家肯定不陌生了,在读reference的两篇blog时突然发现用python实现单例模式的很多好玩之处。 用类实现单例模式是各种语言比较通用的方式。在python中的实现就

    2024年02月16日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包