单例
配置文件
IP = '1.1.1.1'
PORT = '3306'
单例1.py
# 单例模式 (省内存)
# 基于某种方法实例化多次得到的实例是同一个
# 为何用单例模式
# 当实例化多次得到的对象中存取的属性都一样的情况下,应该将多个对象指向同一个内存,即同一个实例
# 如何用:
# 实现单例方式一
import settings
class Mysql():
__isinstance = None
def __init__(self,ip,port):
self.ip = ip
self.port = port
@classmethod
def from_conf(cls):
if cls.__isinstance is None:
cls.__isinstance = cls(settings.IP,settings.PORT)
return cls.__isinstance
obj1 = Mysql.from_conf()
obj2 = Mysql.from_conf()
obj3 = Mysql.from_conf()
print(obj1)
print(obj2)
print(obj3)
# <__main__.Mysql object at 0x1033a57f0>
# <__main__.Mysql object at 0x1033a5ac8>
# <__main__.Mysql object at 0x1033a5b70>
# 仅适用于对象中存的东西一样
# <__main__.Mysql object at 0x1033a57b8>
# <__main__.Mysql object at 0x1033a57b8>
# <__main__.Mysql object at 0x1033a57b8>
# 不一样的单独造
obj4 = Mysql('2.2.2.2',3309)
print(obj4)
单例2装饰器.py
# 实现单例方式二
import settings
# 如果是从配置文件里面获取配置的话
# 装饰器
def singleton(cls): #func传被装饰的函数,类
_instance = cls(settings.IP,settings.PORT) #放到类里面变成类属性 cls.__instance
def wrapper(*args,**kwargs):
if not args and not kwargs:
return _instance
return cls(*args,**kwargs)
return wrapper
@singleton
class Mysql():
def __init__(self,ip,port):
self.ip = ip
self.port = port
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
print(obj1 is obj2 is obj3)
obj4 = Mysql('2.2.2.2',3309)
print(obj1)
print(obj2)
print(obj3)
print(obj4)
# # 运行过程,遇到@语法就会将装饰器正下方的那个名字当做参数传进来,然后将返回的结果重新赋值给这个名字:
# @singleton #Mysql = singleton(Mysql)
# class Mysql():
# def __init__(self, ip, port):
# self.ip = ip
# self.port = port
#
#
#
# # singleton调用发生了
# def singleton(cls): #cls = Mysql @singleton #Mysql = singleton(Mysql) Mysal = wrapper
# def wrapper(*args,**kwargs):
# res = cls(*args,**kwargs)
# return res
# return wrapper
# obj = Mysql('1.1.1.1',3306)
# print(obj.__dict__)
单例3元类.py
# 实现单例方式三
import settings
class Mymeta(type):
def __init__(self,class_name, class_bases, class_dic): #在Mysql造出来之前发生的 self = Mysql
super(Mymeta, self).__init__(class_name, class_bases, class_dic)
obj = self.__new__(self) #造出一个Mysql的对象
self.__init__(obj,settings.IP,settings.PORT) #从配置文件中加载配置完成Mysql对象的初始化
# 保存下来
self.__instance = obj
# print(self.__instance)
# print(self.__instance.__dict__)
def __call__(self, *args, **kwargs):
if len(args) == 0 and len(kwargs) == 0:
return self.__instance
obj = self.__new__(self)
self.__init__(obj,*args,**kwargs)
return obj
class Mysql(object,metaclass=Mymeta):
def __init__(self,ip,port):
self.ip = ip
self.port = port
# Mysql()
obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
obj4 = Mysql('2.2.2.2',3309)