• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
龙三少
博客园    首页    新随笔    联系   管理    订阅  订阅

单例模式以及四种实现方法

目录
  • 单例模式
    • 一、什么是单例模式
    • 二、实现单例模式的四种方法
      • 2.1 定义一个类方法实现单例模式
      • 2.2 定义一个装饰器实现单例模式
      • 2.3 定义一个元类实现单例模式
      • 2.4 通过模块导入实现单例模式(python的模块是天然的单例)

单例模式

一、什么是单例模式

类的设计模式有23种

单例模式是其中一种设计模式

单例模式:即单个实例,指的是同一个类实例化多次的结果都指向同一个对象,可以用于节省内存空间

二、实现单例模式的四种方法

举例:当用户输入端口和地址,实例化产生新对象

​ 当用户不输入端口和地址,每次拿到的对象都是同一个

需要创建一个settings文件配置端口和地址数据

2.1 定义一个类方法实现单例模式

class Sql():
    _instance = None
    def __init__(self,post,host):
        self.post = post
        self.host = host
    # @classmethod
    # def get_sigoleton(cls):     
    #     import settings
    #     if cls._instance:
    #         return cls._instance
    #     else:
    #         cls._instance=cls(settings.PORT,settings.HOST)
    #         return cls._instance
    # 下面这种和上面一样,判断对象是否为空,空的就实例化产生对象
    @classmethod
    def get_sigonleton(cls):
        import settings
        if not cls._instance:
            cls._instance = cls(settings.POST,settings.HOST)
        return cls._instance 

s1=Sql.get_sigonleton()
s2=Sql.get_sigonleton()
print(s1)
print(s2)

2.2 定义一个装饰器实现单例模式

# 先定义一个装饰器
def get_sigonleton(cls):
    import settings
    _instance = cls(settings.PORT,settings.HOST)
    def wrapper(*args,**kwargs):
        if len(args) != 0 or len(kwargs) != 0:
            # 表示传了参数,生成新对象
            res = cls(*args,**kwargs)
            return res
        else:
            return _instance
    return wrapper

@get_sigonleton
class Sql():
    def __init__(self,port,host):
        self.port = port
        self.host = host

s1=Sql()
s2=Sql()
print(s1)  # <__main__.Sql object at 0x0000026A68DB9390>
print(s2)  # <__main__.Sql object at 0x0000026A68DB9390> 两个对象都指向同一个内存地址
s3=Sql(3308,'192.168.1.3')
print(s3)  # <__main__.Sql object at 0x0000026A68BFCE48> 用户输入数据就得到新对象

2.3 定义一个元类实现单例模式

class Mymeta(type):
    def __init__(self,name,bases,dic):
        import settings
        # 把实例化好的对象,放到了类的名称空间
        self._instance = self(settings.PORT,settings.HOST)
    def __call__(self, *args, **kwargs):
        # 2、进行判断
        if len(args) != 0 or len(kwargs) != 0:
            obj = object.__new__(self)
            obj.__init__(*args, **kwargs)
            return obj
        else:
            return self._instance

class Sql(metaclass=Mymeta):  # 相当于Sql=Mymeta(name,bases,dic),这个会调用Mymeta的__init__方法
    def __init__(self,port,host):
        self.port = port
        self.host = host

s1 = Sql()
# 1、调用元类的__call__
s2 = Sql()
print(s1)
print(s2)

2.4 通过模块导入实现单例模式(python的模块是天然的单例)

# 这个方法需要先创建一个sigonleton.py文件,把类Sql的定义和实例化放到这个文件中
# 然后在本文件导入sigonleton.py中的s1
def test():
    from sigonleton import s1
    print(s1)
def test2():
    from sigonleton import s1
    print(s1)
test()
test2()

https://www.cnblogs.com/zhuangyl23/

posted @ 2019-09-04 14:13  柠檬要加醋  阅读(726)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3