前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >20·Python基础-单例模式四种实现方式

20·Python基础-单例模式四种实现方式

作者头像
DriverZeng
发布2022-09-26 12:33:20
2260
发布2022-09-26 12:33:20
举报
文章被收录于专栏:Linux云计算及前后端开发

-曾老湿, 江湖人称曾老大。


-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。


单例模式介绍


什么是单例模式

单例模式:多次实例化的结果指向同一个实例

是面向对象的一种设计模式


举例

代码语言:javascript
复制
class MySQL:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

# 第一次实例化
obj1=MySQL('1.1.1.1',3306)

# 再一次实例化,又得到一个容器
obj2=MySQL('1.1.1.1',3306)

# 第三次实例化
obj3=MySQL('1.1.1.1',3306)

## 我们经过三次实例化会发现,会产生3个内存地址,这三个内存地址存储的数据都是一样的,所以我们没有必要存储那么多次。

## 所以单例模式的作用,就是把结果指向一个实例,如此一来,我们就可以做到节省资源

## 例如我们之前实现 过的,使用settings.py文件来存储数据,然后导入 

### settings.py
IP='1.1.1.1'
PORT=3306

### 导入settings.py文件
import settings

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

obj1=MySQL(settings.IP, settings.PORT)
obj2=MySQL(settings.IP, settings.PORT)
obj3=MySQL(settings.IP, settings.PORT)

实现单例模式的第一种方式

代码语言:javascript
复制
import settings

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

    @classmethod
    def from_conf(cls):
        return cls(settings.IP,settings.PORT)

obj1=MySQL.from_conf()
obj2=MySQL.from_conf()
obj3=MySQL.from_conf()
print(obj1)
print(obj2)
print(obj3)
# 比原来精简了,但是没有实现单例
import settings

class MySQL:
    __instance=None
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    @classmethod
    def from_conf(cls):
        if cls.__instance is None:
            cls.__instance=cls(settings.IP, settings.PORT)
        return cls.__instance
obj1=MySQL.from_conf()
obj2=MySQL.from_conf()
obj3=MySQL.from_conf()

obj4=MySQL('1.1.1.3',3302)
print(obj1)
print(obj2)
print(obj3)
print(obj4)

实现单例模式的第二种方式

使用装饰器来实现

代码语言:javascript
复制
import settings

def singleton(cls):
    def wrapper(*args,**kwargs):
        instance=cls(*args,**kwargs)
        return instance
    return wrapper

@singleton #MySQL=singleton(MySQL) #MySQL=wrapper
class MySQL:
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

obj=MySQL('1.1.1.1',3306) #obj=wrapper('1.1.1.1',3306)
print(obj.__dict__)
## 目前装饰器 ,什么功能都没有实现,我们要定制,MySQL内不传递任何参数就返回已经定义好的对象


import settings

def singleton(cls):
    _instance=cls(settings.IP,settings.PORT)
    def wrapper(*args,**kwargs):
        if len(args) !=0 or len(kwargs) !=0:
            obj=cls(*args,**kwargs)
            return obj
        return _instance
    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()
obj4=MySQL('1.1.1.3',3302) #wrapper('1.1.1.3',3302)
print(obj1)
print(obj2)
print(obj3)
print(obj4)

实现单例模式的第三种方式

使用元类来实现单例模式

代码语言:javascript
复制
import settings

class Mymeta(type):
    def __init__(self,class_name,class_bases,class_dic):
        #self=MySQL这个类
        self.__instance=self(settings.IP,settings.PORT)

    def __call__(self, *args, **kwargs):
        # self=MySQL这个类
        if len(args) != 0 or len(kwargs) != 0:
            obj=self.__new__(self)
            self.__init__(obj,*args, **kwargs)
            return obj
        else:
            return self.__instance

class MySQL(metaclass=Mymeta): #MySQL=Mymeta(...)
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

obj1=MySQL()
obj2=MySQL()
obj3=MySQL()
obj4=MySQL('1.1.1.3',3302)
print(obj1)
print(obj2)
print(obj3)
print(obj4)

实现单例模式的第四种方式

使用导入模块的方式

settings.py

代码语言:javascript
复制
IP='1.1.1.1'
PORT=3306

singleton.py

代码语言:javascript
复制
import settings

class MySQL:
    print('run....')
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

instance=MySQL(settings.IP,settings.PORT)

导入singleton模块并调用

代码语言:javascript
复制
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()

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-04-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单例模式介绍
  • 实现单例模式的第一种方式
  • 实现单例模式的第二种方式
  • 实现单例模式的第三种方式
  • 实现单例模式的第四种方式
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档