凉城旧巷
Python从入门到自闭,Java从自闭到放弃,数据库从删库到跑路,Linux从rm -rf到完犊子!!!

单例模式

一、什么是单例

即单个实例,指的是同一个类实例化多次的结果指向同一个对象,用于节省内存空间

如果我们从配置文件中读取配置来进行实例化,在配置相同的情况下,就没必要重复产生对象浪费内存了

# settings.py文件
IP = '1.1.1.1'
PORT = 3303

二、四种单例模式的实现方式

# 方式一:定义一个类方法实现单例模式

import settings

class People:
    __instance = None    #用于保存实例化的状态

    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    @classmethod
    def get(cls):
        if cls.__instance is None:
            cls.__instance = cls(settings.IP, settings.PORT)
        return cls.__instance


obj1 = People.get()
obj2 = People.get()
print(obj1)
print(obj2)
# <__main__.People object at 0x00000000021BA9B0>
# <__main__.People object at 0x00000000021BA9B0>




#方式二:定义一个装饰器实现单例模式
import settings

def singlet(cls):
    _instance = cls(settings.IP, settings.PORT)   #先实例化一个对象

    def wrapper(*args, **kwargs):
        if args or kwargs:
            obj = cls(*args, **kwargs)
            return obj        #有参数是返回后来实例化对象
        return _instance         #无参时,返回已经实例化好的对象

    return wrapper


@singlet    # MySQL=wrapper(MySQL)
class MySQL:

    def __init__(self, ip, port):
        self.ip = ip
        self.port = port


# 没有参数时,单例模式
obj1 = MySQL()
obj2 = MySQL()
obj3 = MySQL()
obj4 = MySQL('1.1.1.1', 3303)
print(obj1)
print(obj2)
print(obj3)
print(obj4)
# <__main__.MySQL object at 0x0000000001E6AA90>
# <__main__.MySQL object at 0x0000000001E6AA90>
# <__main__.MySQL object at 0x0000000001E6AA90>
# <__main__.MySQL object at 0x0000000001E6AB00>


#方式三:定制元类实现单例模式
import settings

class Mymeta(type):
    def __init__(self, class_name, class_bases, class_dic):
        instance = self(settings.IP, settings.PORT)
        self.__instance = instance

    def __call__(self, *args, **kwargs):         # self=MySQL
        if args or kwargs:          #  有参数执行下面的代码
            obj = self.__new__(self)          #创造一个空对象
            self.__init__(obj, *args, **kwargs)          #初始化
            return obj             #返回对象
        return self.__instance


class MySQL(metaclass=Mymeta):
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port


obj1 = MySQL()
obj2 = MySQL()
obj3 = MySQL()
obj4 = MySQL('1.2.3.1', 3305)
print(obj1)
print(obj2)
print(obj3)
print(obj4)
# <__main__.MySQL object at 0x00000000021BAA90>
# <__main__.MySQL object at 0x00000000021BAA90>
# <__main__.MySQL object at 0x00000000021BAA90>
# <__main__.MySQL object at 0x00000000021BAB00>


方式四:利用模块导入实现单例模式
# singleton模块
import settings


class MySQL:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port


instance = MySQL(settings.IP, settings.PORT)

#单例模块
def f1():
    from singleton import instance
    print(instance)


def f2():
    from singleton import instance, MySQL
    print(instance)
    obj = MySQL('1111', 3302)
    print(obj)


f1()
f2()

# <singleton.MySQL object at 0x00000000021FAA90>
# <singleton.MySQL object at 0x00000000021FAA90>
# <singleton.MySQL object at 0x00000000021FA358>

 

posted on 2018-08-28 15:04  凉城旧巷  阅读(136)  评论(0编辑  收藏  举报