Blueherb In solitude, where we are least alone

day30

单例模式
什么是单例模式
单例模式:基于某种方法实例化多次得到实例是同一个
为什么用单例模式
当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例
用类方法来实现单例模式

settings.py

IP = '1.1.1.1'
PORT = 3306

class Mysql:
__instacne = None

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

@classmethod
def from_conf(cls):
    if cls.__instacne is None:
        cls.__instacne = cls(IP, PORT)
    return cls.__instacne

obj1 = Mysql.from_conf()
obj2 = Mysql.from_conf()
obj3 = Mysql.from_conf()
print(obj1 is obj2 is obj3)
True
print(obj1.dict)
print(obj2.dict)
print(obj3.dict)
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
obj4 = Mysql('10.10.10.11', 3307)
print(obj4.dict)
{'ip': '10.10.10.11', 'port': 3307}
用装饰器实现单例模式

settings.py

IP = '1.1.1.1'
PORT = 3306

def singleton(cls):
cls.__instance = cls(IP, PORT)

def wrapper(*args, **kwargs):
    if len(args) == 0 and len(kwargs) == 0:
        return cls.__instance
    return cls(*args, **kwargs)

return wrapper

@singleton # Mysql = singleton(Mysql) # Mysql = wrapper
class Mysql:
def init(self, ip, port):
self.ip = ip
self.port = port

obj1 = Mysql() # wrapper()
obj2 = Mysql() # wrapper()
obj3 = Mysql() # wrapper()
print(obj1 is obj2 is obj3)
True
print(obj1.dict)
print(obj2.dict)
print(obj3.dict)
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
obj4 = Mysql('1.1.1.4', 3308)
print(obj4.dict)
{'ip': '1.1.1.4', 'port': 3308}
用元类实现单例模式

settings.py

IP = '1.1.1.1'
PORT = 3306

class Mymeta(type):
def init(self, class_name, class_bases, class_dic): # self = Mysql
super(Mymeta, self).init(class_name, class_bases, class_dic)

    # 完成Mysql对象的初始化
    self.__instance = self.__new__(self)  # 造出一个Mysql的对象
    self.__init__(self.__instance, IP, PORT)  # 从配置文件中加载配置完成Mysql对象的初始化

    print(self.__instance)
    print(self.__instance.__dict__)

def __call__(self, *args, **kwargs):  # self = Mysql
    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): # Mysql = Mymeta(...)
def init(self, ip, port):
self.ip = ip
self.port = port

obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()
<main.Mysql object at 0x10c7f1f98>
{'ip': '1.1.1.1', 'port': 3306}
print(obj1 is obj2 is obj3)
True
print(obj1.dict)
print(obj2.dict)
print(obj3.dict)
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
{'ip': '1.1.1.1', 'port': 3306}
obj4 = Mysql('10.10.10.11', 3308)

print(obj4.dict)
{'ip': '10.10.10.11', 'port': 3308}
print(Mysql.dict)
{'module': 'main', 'init': <function Mysql.init at 0x10c6b1d90>, 'dict': <attribute 'dict' of 'Mysql' objects>, 'weakref': <attribute 'weakref' of 'Mysql' objects>, 'doc': None, '_Mymeta__instance': <main.Mysql object at 0x10c7f1f98>}

posted @ 2019-09-11 19:29  奏乐乐章  阅读(107)  评论(0编辑  收藏  举报