python 单例模式的实现 Python单例模式剖析 Python中的单例模式的几种实现方式的及优化

一、单例模式

单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费!!!

单例模式的好处和缺点?为什么要用单例模式?

Python单例模式剖析

Python中的单例模式的几种实现方式的及优化

二、实现

1. 适用模块

Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。

2. 装饰器

# -*- coding: utf-8 -*-


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


if __name__ == '__main__':
    a = MyClass()
    b = MyClass()
    print(a, b)
    b.a = 4
    print(a.a, b.a)

3. __new__() (线程同步)

# -*- coding: utf-8 -*-
# https://www.jb51.net/article/135156.htm
import threading


class Singleton(object):
    _instance_lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with cls._instance_lock:
                if not hasattr(cls, '_instance'):
                    cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance


if __name__ == '__main__':
    obj1 = Singleton()
    obj2 = Singleton()
    print(obj1, obj2)


    def task(arg):
        obj = Singleton()
        print(obj)


    for i in range(10):
        t = threading.Thread(target=task, args=[i, ])
        t.start()

4. metaclass

# -*- coding: utf-8 -*-

import threading


class SingletonMetaclass(type):
    _instance_lock = threading.Lock()

    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with cls._instance_lock:
                if not hasattr(cls, '_instance'):
                    cls._instance = super(SingletonMetaclass, cls).__call__(cls, *args, **kwargs)
        return cls._instance


class Foo(metaclass=SingletonMetaclass):
    def __init__(self, name):
        self.name = name


if __name__ == '__main__':
    obj1 = Foo()
    obj2 = Foo()
    print(obj1, obj2)


    def task(arg):
        obj = Foo()
        print(obj)


    for i in range(10):
        t = threading.Thread(target=task, args=[i, ])
        t.start()

猜你喜欢

转载自www.cnblogs.com/charlieLeo/p/9540946.html