单例:某一个类只有一个实例
实现方式 一、使用类方法(调用创新对象,函数返回原定对象)
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()