首页 > 编程语言 > 详细

python单例模式

时间:2020-06-15 00:50:29      阅读:60      评论:0      收藏:0      [点我收藏+]

1. 什么是单例模式

单例模式是一种常见的软件设计模式。主要是确保一个类只有一个实例存在。单例模式可以节约系统资源

2. 常见应用场景

技术分享图片

3.  实现单例模式的方法

3.1 __new__方法

class Animal(object):

    instance = None

    @staticmethod
    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = super(Animal, cls).__new__(cls)
        return cls.instance


dog = Animal()
cat = Animal()
print(id(dog))
print(id(cat))

3.2  装饰器

def singleton(cls):
    """单例模式装饰器"""
    instance = {}

    def get_instance():
        if cls not in instance:
            instance[cls] = cls()
        return instance[cls]

    return get_instance


@singleton
class Animal(object):
    def __init__(self):
        pass

3.3  使用元类

class Animal(type):
    """使用元类实现单例模式"""
    instance = None

    def __call__(cls):
        if not cls.instance:
            cls.instance = super(Animal, cls).__call__()
        return cls.instance


class Dog(metaclass=Animal):
    pass

3.4 使用模块

创建一个类的实例,然后在其他文件里import进去。

3.5 使用类创建单例模式

class Animal(object):
    """使用元类实现单例模式"""
    def __init__(self):
        pass

    @staticmethod
    def get_instance():
        if not hasattr(Animal, "_instance"):
            Animal._instance = Animal()
        return Animal._instance


def create_singleton():
    small_animal = Animal.get_instance()
    print(id(small_animal))


create_singleton()
create_singleton()

技术分享图片

注:这样的单例模式在单线程下是安全的,但是如果遇到多线程,就会出现问题。示例代码如下:

import time
from concurrent.futures import ThreadPoolExecutor


class Animal(object):
    """使用元类实现单例模式"""
    def __init__(self):
        time.sleep(1)
        pass

    @staticmethod
    def get_instance():
        if not hasattr(Animal, "_instance"):
            Animal._instance = Animal()
        return Animal._instance


def create_singleton():
    small_animal = Animal.get_instance()
    print(id(small_animal))


if __name__ == "__main__":
    with ThreadPoolExecutor(max_workers=10) as executor:
        for i in range(10):
            executor.submit(create_singleton)

运行结果如下图所示,创建了10个实例。

技术分享图片

 

 

 解决:加锁。在在获取对象属性_instance的时候加锁,加锁后的代码如下:

import time
from concurrent.futures import ThreadPoolExecutor
import threading


class Animal(object):
    """使用元类实现单例模式"""
    _lock = threading.Lock()

    def __init__(self):
        time.sleep(1)

    @staticmethod
    def get_instance():
        if not hasattr(Animal, "_instance"):
            with Animal._lock:
                if not hasattr(Animal, _instance):
                    Animal._instance = Animal()
        return Animal._instance


def create_singleton():
    small_animal = Animal.get_instance()
    print(id(small_animal))


if __name__ == "__main__":
    with ThreadPoolExecutor(max_workers=10) as executor:
        for i in range(10):
            executor.submit(create_singleton)

技术分享图片

 

python单例模式

原文:https://www.cnblogs.com/theshy1103/p/13127466.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!