单例模式

单例模式

什么是单例模式

  • 单例模式:基于某种方法实例化多次得到实例是同一个

为什么用单例模式

  • 当实例化多次得到的对象中存放的属性都一样的情况,应该将多个对象指向同一个内存,即同一个实例

用类方法来实现单例模式

# 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>}

转载于:https://www.cnblogs.com/TMesh-python/p/11568114.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值