python3 - 单例模式,及其实现方式

单例:某一个类只有一个实例

实现方式 一、使用类方法(调用创新对象,函数返回原定对象)

import settings
class Mysql:
    __instance = None

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

    @classmethod
    def singleton(cls):
        if not cls.__instance:
            # 创建类实例存入局部空间
            cls.__instance = cls(settings.IP, settings.PORT)
        return cls.__instance


# 使用init创建实例
obj1 = Mysql('1.1.1.2', 3306)
obj2 = Mysql('1.1.1.3', 3307)
print(obj1 is obj2)  # False

# 使用类方法创建实例
obj3 = Mysql.singleton()
obj4 = Mysql.singleton()
print(obj3 is obj4)  # True

实现方式 二、定义装饰器(有参创建新对象,无参返回原对象)

import settings


def singleton(cls):  # cls=Mysql
    _instance = cls(settings.IP, settings.PORT)

    def wrapper(*args, **kwargs):
        # 如果有参数传入,则产生对象;若没有参数,返回原对象
        if args or kwargs:
            # 装饰器传入类,调用类产生对象,返回对象
            obj = cls(*args, **kwargs)
            return obj
        return _instance

    return wrapper


@singleton  # Mysql=singleton(Mysql)
class Mysql:
    def __init__(self, host, port):
        self.host = host
        self.port = port


# 无参调用,返回同一个原定对象
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj1 is obj2 is obj3)  # True
# 有参调用,返回新建对象
obj4 = Mysql('1.1.1.3', 3307)
obj5 = Mysql('1.1.1.4', 3308)
print(obj3 is obj4)  # False

实现方式 三、元类实现(有参创建新对象,无参返回原对象)

import settings


class Mymeta(type):
    def __init__(self, name, bases, dic):  # 定义类Mysql时就触发
        # 1.事先先从配置文件中取配置来造一个Mysql的实例出来
        self.__instance = self(settings.IP, settings.PORT)

    def __call__(self, *args, **kwargs):  # Mysql(...)时触发
        if args or kwargs:  # args或kwargs内有值
            # 创建新的对象
            obj = object.__new__(self)
            self.__init__(obj, *args, **kwargs)
            return obj
        # 返回局部内原有对象
        return self.__instance


# 定义时,跳到元类内init初始对象
class Mysql(metaclass=Mymeta):
    def __init__(self, host, port):
        self.host = host
        self.port = port


obj1 = Mysql()  # 没有传值则默认从配置文件中读配置来实例化,所有的实例应该指向一个内存地址
obj2 = Mysql()
obj3 = Mysql()
obj4 = Mysql('1.1.1.4', 3307)
print(obj1 is obj2 is obj3)
print(obj1 is obj2 is obj4)

实现方式 四、模块实现

-配置文件settings

IP = '192.168.1.1'
PORT = 3306

-模块文件 singleton

import settings


class MySQL:
    print('run....')

    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('1.1.1.3',3302)
    print(obj)
f1()
f2()

猜你喜欢

转载自blog.csdn.net/qq_33961117/article/details/82148022