python单例模式

简介: 单例模式是一种常用的软件设计模式.在单例模式的核心结构中,只包含一个被称为单例类的特殊类.通过单例模式可以保证系统中一个类只有一个实例,而且这个实例可以轻易被外界访问,方便控制实例对象的个数以节约系统资源.

单例模式是一种常用的软件设计模式.

在单例模式的核心结构中,只包含一个被称为单例类的特殊类.

通过单例模式可以保证系统中一个类只有一个实例,而且这个实例可以轻易被外界访问,方便控制实例对象的个数以节约系统资源.

单例模式是解决一个系统中某个类的实例化对象有且只能有一个的最好解决方案.

单例模式的要点有三个:

  • 某个类只能有一个实例
  • 这个类必须自行创建其唯一实例
  • 这个类必须自行向整个系统提供这个唯一实例.

在python中,单例模式有三种实现方式:

方法一,使用__new__方法

先定义一个类,类中定义__new__方法,然后将类的一个实例类绑定到类变量中.

如果类的_instance值为None,则说明这个类还没有被实例化过,程序会自动实例化一个类的实例,然后返回.

如果类的_instance值不为None,则程序会直接返回_instance.

代码如下:

class Singleton(object):

    _instance = None
    
    def __init__(self):
        pass
    
    def __new__(cls, *args, **kwargs):
    
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)  
        return cls._instance  
 
class MyClass(Singleton):  
    a = 1

在上面的代码中,我们将类的实例和一个类变量 _instance关联起来.

如果 cls._instance为 None 则创建实例,否则直接返回cls._instance

用上来定义的类实例化两个对象:

cls1=MyClass()
cls2=MyClass()

print(id(cls1))
print(id(cls2))

print(cls1 == cls2)
print(cls1 is cls2)

得到的结果

43606480
43606480
True
True

方法二,使用decorator装饰器

我们知道,装饰器(decorator)可以动态地修改一个类或函数的功能。

在这里使用装饰器来装饰某个类,使其只能生成一个实例,代码如下:

def singleton(cls):
    instances={}

    def getinstance(*args,**kwargs):
        if cls not in instances:
            instances[cls]=cls(*args,**kwargs)

        return instances[cls]
    return getinstance

@singleton
class MyClass(object):
    a=1

在上面,我们定义了一个装饰器singleton,它返回了一个内部函数getinstance,该函数会判断某个类是否在字典instances中,

如果不存在,则会将cls作为key,cls(*args, **kw)作为value存到instances中,否则,直接返回instances[cls]

使用上面定义的类实例化两个对象,比较两个对象

cls1=MyClass()
cls2=MyClass()

print(id(cls1))
print(id(cls2))

print(cls1 == cls2)
print(cls1 is cls2)

得到的结果为:

43672016
43672016
True
True

方法三,使用元类(metaclass)

元类(metaclass)可以控制类的创建过程,它主要做三件事:

拦截类的创建
修改类的定义
返回修改后的类

用元类实现单例模式的代码如下:

    class Singleton(type):
        _inst = {}
    
        def __call__(self, *args, **kw):
            if self not in self._inst:
                self._inst[self] = super(Singleton, self).__call__(*args, **kw)
            return self._inst[self]
    
    class MyClass(metaclass=Singleton):
        def __init__(self):
            self.xx = 0

    cls1=MyClass()
    cls2=MyClass()

    print(id(cls1))
    print(id(cls2))

    print(cls1 == cls2)
    print(cls1 is cls2)

得到的结果为:

43477984
43477984
True
True

方法四,使用classmethod方法创建单例模式

class Foo:
    _instance = None

    def __init__(self):
        pass

    @classmethod
    def get_instance(cls):
        if cls._instance:
            return cls._instance
        else:
            obj=cls()
            cls._instance=obj
            return obj

cls1=Foo.get_instance()     # 实例化对象a1时,没有执行Foo这个类的__init__方法,直接执行Foo类的get_instance方法,在这里cls代指的是Foo类
                            # 前面把_instance赋值为None,所以直接执行else中的语句,实例化一个obj对象,然后把obj对象中的_instance方法赋值为obj对象本身,然后返回obj对象
cls2=Foo.get_instance()     # 实例化a1时,Foo类中的_instance已经被赋值为obj对象,所以再次执行Foo中的get_instance方法时,是执行if中的语句
                            # 此时cls._instance就指的是obj对象,所以这里也返回obj这个对象
print(id(cls1))
print(id(cls2))

print(cls1 == cls2)
print(cls1 is cls2)

这种方法由于在实例化对象时要调用类中的get_instance方法,所以用的不多,知道即可.

特别声明

Python的模块是天然的单例模式

在一个py文件中,多次导入同一个模块,这个模块也只有在第一次的时候被导入,后续的该模块导入语句都不会再执行了

目录
相关文章
|
6月前
|
Python
如何在Python中实现单例模式?
【1月更文挑战第15天】
47 2
|
29天前
|
设计模式 存储 数据库连接
Python编程中的设计模式之美:单例模式的妙用与实现###
本文将深入浅出地探讨Python编程中的一种重要设计模式——单例模式。通过生动的比喻、清晰的逻辑和实用的代码示例,让读者轻松理解单例模式的核心概念、应用场景及如何在Python中高效实现。无论是初学者还是有经验的开发者,都能从中获得启发,提升对设计模式的理解和应用能力。 ###
|
2月前
|
设计模式 缓存 数据库
Python中的单例模式
单例模式确保一个类只有一个实例,并提供全局访问点。此模式常用于共享资源或限制资源访问,可避免资源浪费并简化全局访问。其实现方法包括使用模块级变量、装饰器或元类。尽管单例模式能简化访问和初始化,但也可能引入全局状态,影响代码的可维护性。适用于配置管理、数据库连接池等场景。
|
3月前
|
设计模式 存储 数据库连接
Python设计模式:巧用元类创建单例模式!
Python设计模式:巧用元类创建单例模式!
48 0
|
5月前
|
设计模式 测试技术 数据库
Python单例模式详解与实际应用
单例模式是一种特殊的设计模式,它通过限制一个类的实例数量为一个来保证只有一个实例被创建,并且提供一个全局访问点以供其他对象使用。
81 3
|
4月前
|
设计模式 缓存 数据库
Python中的单例模式是什么?
**摘要:** 单例模式是一种设计模式,确保类只有一个实例并提供全局访问点。常用于共享资源、配置管理、数据库连接池、日志记录和缓存。Python中可使用模块级变量、装饰器或元类实现单例。需谨慎使用,以避免全局状态导致的复杂性。
|
6月前
|
存储 安全 Python
如何在Python中实现一个单例模式,确保在多线程环境中也是安全的?
【2月更文挑战第5天】【2月更文挑战第11篇】如何在Python中实现一个单例模式,确保在多线程环境中也是安全的?
183 1
|
6月前
|
存储 安全 Python
|
Python
62 python - 单例模式
62 python - 单例模式
30 0
|
缓存 安全 开发者
Python 单例模式讲解和代码示例
Python 单例模式讲解和代码示例
49 0