Python 单例模式讲解和代码示例

简介: Python 单例模式讲解和代码示例

使用示例许多开发者将单例模式视为一种反模式 因此它在 Python 代码中的使用频率正在逐步减少

识别方法单例可以通过返回相同缓存对象的静态构建方法来识别

01基础单例


实现一个粗糙的单例非常简单 你仅需隐藏构造函数并实现一个静态的构建方法即可

相同的类在多线程环境中会出错 多线程可能会同时调用构建方法并获取多个单例类的实例

main.py: 概念示例


classSingletonMeta(type):

 

"""
    The Singleton class can be implemented in different ways in Python. Some
    possible methods include: base class, decorator, metaclass. We will use the
    metaclass because it is best suited for this purpose.
    """
    _instances = {}
    def __call__(cls, *args, **kwargs):
        """
        Possible changes to the value of the `__init__` argument do not affect
        the returned instance.
        """
        if cls not in cls._instances:
            instance = super().__call__(*args, **kwargs)
            cls._instances[cls] = instance
        return cls._instances[cls]
class Singleton(metaclass=SingletonMeta):
    def some_business_logic(self):
        """
        Finally, any singleton should define some business logic, which can be
        executed on its instance.
        """
        #...
if __name__ == "__main__":
    #The client code.
    s1 = Singleton()
    s2 = Singleton()
    if id(s1) == id(s2):
        print("Singleton works, both variables contain the same instance.")
    else:
        print("Singleton failed, variables contain different instances.")

 Output.txt: 执行结果

Singleton works, both variables contain the same instance.

02线程安全单例


为了解决这个问题 你必须在创建首个单例对象时对线程进行同步

main.py: 概念示例

from threading import Lock, Thread
class SingletonMeta(type):
    """
    This is a thread-safe implementation of Singleton.
    """
    _instances = {}
    _lock: Lock = Lock()
    """
    We now have a lock object that will be used to synchronize threads during
    first access to the Singleton.
    """
    def __call__(cls, *args, **kwargs):
        """
        Possible changes to the value of the `__init__` argument do not affect
        the returned instance.
        """
        #Now, imagine that the program has just been launched. Since there's no
        #Singleton instance yet, multiple threads can simultaneously pass the
        #previous conditional and reach this point almost at the same time. The
        #first of them will acquire lock and will proceed further, while the
        #rest will wait here.
        with cls._lock:
            #The first thread to acquire the lock, reaches this conditional,
            #goes inside and creates the Singleton instance. Once it leaves the
            #lock block, a thread that might have been waiting for the lock
            #release may then enter this section. But since the Singleton field
            #is already initialized, the thread won't create a new object.
            if cls not in cls._instances:
                instance = super().__call__(*args, **kwargs)
                cls._instances[cls] = instance
        return cls._instances[cls]
class Singleton(metaclass=SingletonMeta):
    value: str = None
    """
    We'll use this property to prove that our Singleton really works.
    """
    def __init__(self, value: str) -> None:
        self.value = value
    def some_business_logic(self):
        """
        Finally, any singleton should define some business logic, which can be
        executed on its instance.
        """
def test_singleton(value: str) -> None:
    singleton = Singleton(value)
    print(singleton.value)
if __name__ == "__main__":
    #The client code.
    print("If you see the same value, then singleton was reused (yay!)\n"
          "If you see different values, "
          "then 2 singletons were created (booo!!)\n\n"
          "RESULT:\n")
    process1 = Thread(target=test_singleton, args=("FOO",))
    process2 = Thread(target=test_singleton, args=("BAR",))
    process1.start()
    process2.start()

Output.txt: 执行结果

If you see the same value, then singleton was reused (yay!)
If you see different values, then 2 singletons were created (booo!!)
RESULT:
FOO
FOO
相关文章
|
6天前
|
Python
Python代码扫描目录下的文件并获取路径
【5月更文挑战第12天】Python代码扫描目录下的文件并获取路径
24 1
|
6天前
|
数据处理 Python
Python 代码中使用。
Python 代码中使用。 z
14 3
|
6天前
|
C++ 开发者 Python
实现Python日志点击跳转到代码位置的方法
本文介绍了如何在Python日志中实现点击跳转到代码位置的功能,以提升调试效率。通过结合`logging`模块的`findCaller()`方法记录代码位置信息,并使用支持点击跳转的日志查看工具(如VS Code、PyCharm),开发者可以从日志直接点击链接定位到出错代码,加快问题排查。
15 2
|
6天前
|
算法 Java 编译器
优化Python代码性能的实用技巧
提高Python代码性能是每个开发者的关注焦点之一。本文将介绍一些实用的技巧和方法,帮助开发者优化他们的Python代码,提升程序的执行效率和性能。
|
1天前
|
数据采集 数据挖掘 Python
最全妙不可言。写出优雅的 Python 代码的七条重要技巧,2024年最新被面试官怼了还有戏吗
最全妙不可言。写出优雅的 Python 代码的七条重要技巧,2024年最新被面试官怼了还有戏吗
|
1天前
|
存储 缓存 API
python源码解读_python代码解释
python源码解读_python代码解释
520专属——使用Python代码表白究竟能不能成功?
520,谐音:“我爱你”,一直觉得,520真正的意义,不单是用于表达爱,也不是为了收礼物和红包,而是提醒我们,不要忘记爱与被爱。 废话不多说,下面整理了9个效果图和参考代码,感兴趣的朋友可以看看
|
1天前
|
机器学习/深度学习 数据采集 数据挖掘
90%的人说Python程序慢,5大神招让你的代码像赛车一样跑起来_代码需要跑很久怎么办(2)
90%的人说Python程序慢,5大神招让你的代码像赛车一样跑起来_代码需要跑很久怎么办(2)
|
1天前
|
Python
|
3天前
|
缓存 开发者 Python
Python中的装饰器:提升代码灵活性与可复用性
众所周知,Python作为一门流行的编程语言,其装饰器(Decorator)机制为代码的优化和重用提供了强大支持。本文将深入探讨Python中装饰器的概念、用法和实际应用,帮助读者更好地理解并应用这一技术,从而提升代码的灵活性和可复用性。