欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python 单例模式

程序员文章站 2024-03-08 10:19:40
...

Python 单例模式

了解Python这么久,一直没有好好去了解一下到底什么是单例模式,今天便去深入探究一下…

单例模式,其实是一种非常简单的设计模式,简单到其实一句话就可以解释:–确保某个类只有一个实例存在。

那么,在什么情况下需要用到单例模式呢?我们就来了解一下单例模式的应用场景:

  • Python的logger就是一个单例模式,用以日志记录;
  • Windows的资源管理器是一个单例模式;
  • 线程池,数据库连接池等资源池一般也用单例模式;
  • 网站计数器等

从这些应用场景我们可以看出单例模式一般应用于:

  • 资源共享的情况下,避免由于资源操作时导致的性能或损耗等,比如:日志文件。
  • 控制资源的情况下,方便资源之间的互相通信,比如:线程池、数据库连接池;网站计数器。

好的,了解完这些以后,我们来看一下Python中单例模式的实现形式。

  1. 使用模块

    Python的模块就是天然的单例模式,因为模块在第一次导入的时候,会生成.pyc文件,第二次导入时会直接加载.pyc文件,而不会再次执行模块代码。

#singleton_test.py
class Singleton_test(object):
	def  foo(self):
		pass
singleton_test = Singleton_test()
#调用
from singleton_test import singleton_test
singleton_test.foo()
  1. new

    使用 new 来控制实例的创建过程

#创建一个类做对比
class Person:
    pass

people1 = Person()
people2 = Person()
print(id(people1),id(people2))
>>>1836223142992 1836223143160
#通过地址可以发现创建了两个实例
#单例
class Person(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        #r如果_instance为空证明是第一次创建实例
        if cls._instance == None:
            #通过父类__new__创建实例
            cls._instance == object.__new__(cls)
            return cls._instance
        else:
            #直接返回上一个对象的引用
            return cls._instance

people1 = Person()
print(id(people1))
people2 = Person()
print(id(people2))
>>>140716233512976
>>>140716233512976
#创建了一个实例   people1 is people2   为 True
  1. 使用装饰器
    装饰器可以动态的修改一个类或函数的功能,所以可以通过装饰器使某个类只能生成一个实例。
from functools import wraps
#装饰器
def person(cls):
    #创建一个存放类
    instance = {}
    @wraps(cls)
    #内部函数
    def getinstance(*args,**kwargs):
        #判断某个类是否存在
        if cls not in instance:
            #cls 作为key,cls(*args,**kwargs)作为value
            instance[cls]  = cls(*args,**kwargs)
        return instance[cls]
    return getinstance
@person
class Person(object):
    pass

people1 = Person()
print(id(people1))
people2 = Person()
print(id(people2))
print(people2 is people1)
>>>2888114661584
>>>2888114661584
>>>True
  • 使用元类(metaclass)
    元类可以控制类的创建过程:

    • 拦截类的创建;
    • 修改类的定义;
    • 返回修改后的类
#定义单例类,因为继承type所以这个类也是元类
class Person(type):
    _instance = {}
    #重写call方法
    def __call__(cls, *args, **kwargs):

        if cls not in cls._instance:
            cls._instance[cls] = super(Person, cls).__call__(*args, **kwargs)

        return cls._instance[cls]
#使用Person元类创建一个类,Son这个类就是Person的实例
class Son(metaclass=Person):
    pass
son1 = Son()
print(id(son1))
son2 = Son()
print(id(son2))
print(son2 is son1)
>>>1476982381816
>>>1476982381816
>>>True
相关标签: Python 单例模式