python 实现单例模式的5种方法


Posted in Python onSeptember 23, 2020

一、classmethod装饰器

# 全局变量
ip = '192.168.13.98'
port = '3306'
class MySQL:
  __instance = None
 
  def __init__(self, ip, port):
    self.ip = ip
    self.port = port
 
  @classmethod
  def instance(cls, *args, **kwargs):
    if args or kwargs:
      cls.__instance = cls(*args, **kwargs)
    return cls.__instance
 
 
obj1 = MySQL.instance(ip, port)
obj2 = MySQL.instance()
obj3 = MySQL.instance()
print(obj1)
print(obj2, obj2.__dict__)
print(obj3, obj3.__dict__)

输出结果

<main.MySQL object at 0x058D6F30>
<main.MySQL object at 0x058D6F30> {'ip': '192.168.13.98', 'port': '3306'}
<main.MySQL object at 0x058D6F30> {'ip': '192.168.13.98', 'port': '3306'}

二、类的装饰器

def singlegon(cls):
  _instance = cls(ip, port)
 
  def wrapper(*args, **kwargs):
    if args or kwargs:
      return cls(*args, **kwargs)
    return _instance
 
  return wrapper
 
 
@singlegon
class MySQL1:
  def __init__(self, ip, port):
    self.ip = ip
    self.port = port
 
 
obj1 = MySQL1()
obj2 = MySQL1()
obj3 = MySQL1('1.1.1.3', 8080)
print(obj1)
print(obj2, obj2.__dict__)
print(obj3, obj3.__dict__)

运行结果

<main.MySQL1 object at 0x04C102B0>
<main.MySQL1 object at 0x04C102B0> {'ip': '192.168.13.98', 'port': '3306'}
<main.MySQL1 object at 0x04C10310> {'ip': '1.1.1.3', 'port': 8080}

三、元类

class Mymetaclass(type):
  def __init__(self, class_name, class_bases, class_dic):
    super().__init__(class_name, class_bases, class_dic)
    self.__instance = self(ip, port)
 
  def __call__(self, *args, **kwargs):
    if args or kwargs:
      obj = self.__new__(self)
      self.__init__(obj, *args, **kwargs)
      self.__instance = obj
    return self.__instance
 
 
class MySQL2(metaclass=Mymetaclass):
  def __init__(self, ip, port):
    self.ip = ip
    self.port = port
 
 
obj1 = MySQL2()
obj2 = MySQL2()
obj3 = MySQL2('1.1.1.3', 80)
print(obj1)
print(obj2, obj2.__dict__)
print(obj3, obj3.__dict__)

运行结果

<main.MySQL2 object at 0x04D003B0>
<main.MySQL2 object at 0x04D003B0> {'ip': '192.168.13.98', 'port': '3306'}
<main.MySQL2 object at 0x04D003D0> {'ip': '1.1.1.3', 'port': 80}

四、模块导入

# instance.py
 
class MySQL:
  def __init__(self, ip, port):
    self.ip = ip
    self.port = port
 
 
ip = '192.168.13.98'
port = 3306
instance = MySQL(ip, port)
 
 
# 测试代码
import os, sys
 
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
from test import instance
 
 
obj1 = instance.instance
obj2 = instance.instance
obj3 = instance.MySQL('1.1.1.3', 80)
print(obj1)
print(obj2, obj2.__dict__)
print(obj3, obj3.__dict__)

运行结果

<day30.instance.MySQL object at 0x052B0AB0>
<day30.instance.MySQL object at 0x052B0AB0> {'ip': '192.168.13.98', 'port': 3306}
<day30.instance.MySQL object at 0x052B03F0> {'ip': '1.1.1.3', 'port': 80}

五、重写__new__()

class MySQL3(object):
  __instance = None
  __first_init = True
 
  def __init__(self, ip, port):
    if self.__first_init:
      self.ip = ip
      self.port = port
      self.__first_init = False
 
  def __new__(cls, *args, **kwargs):
    if not cls.__instance:
      cls.__instance = object.__new__(cls)
    return cls.__instance
 
obj1 = MySQL3(ip, port)
obj2 = MySQL3(ip, port)
obj3 = MySQL3('1.1.1.3', 80)
print(obj1)
print(obj2, obj2.__dict__)
print(obj3, obj3.__dict__)

运行结果

<main.MySQL3 object at 0x059603F0>
<main.MySQL3 object at 0x059603F0> {'ip': '192.168.13.98', 'port': '3306', '_MySQL3__first_init': False}
<main.MySQL3 object at 0x059603F0> {'ip': '192.168.13.98', 'port': '3306', '_MySQL3__first_init': False}

注:前四种可以实现单例模式,但都不是绝对单例模式,可以创建新的对象,但是第五种方式是绝对单例模式,全局只能真正创建一次对象

以上就是python 实现单例模式的5种方法的详细内容,更多关于python 单例模式的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
在Linux上安装Python的Flask框架和创建第一个app实例的教程
Mar 30 Python
Python的函数的一些高阶特性
Apr 27 Python
老生常谈进程线程协程那些事儿
Jul 24 Python
python中的随机函数小结
Jan 27 Python
python 简单照相机调用系统摄像头实现方法 pygame
Aug 03 Python
Python爬虫之正则表达式的使用教程详解
Oct 25 Python
python GUI库图形界面开发之PyQt5树形结构控件QTreeWidget详细使用方法与实例
Mar 02 Python
探秘TensorFlow 和 NumPy 的 Broadcasting 机制
Mar 13 Python
Python内置方法和属性应用:反射和单例(推荐)
Jun 19 Python
Python工程师必考的6个经典面试题
Jun 28 Python
Python学习开发之图形用户界面详解
Aug 23 Python
pytest实现多进程与多线程运行超好用的插件
Jul 15 Python
python zip()函数的使用示例
Sep 23 #Python
python 判断一组数据是否符合正态分布
Sep 23 #Python
python合并多个excel文件的示例
Sep 23 #Python
详解Python yaml模块
Sep 23 #Python
python 绘制场景热力图的示例
Sep 23 #Python
Anaconda使用IDLE的实现示例
Sep 23 #Python
python获取时间戳的实现示例(10位和13位)
Sep 23 #Python
You might like
PHP与MySQL开发中页面乱码的产生与解决
2008/03/27 PHP
php+AJAX传送中文会导致乱码的问题的解决方法
2008/09/08 PHP
php使用反射插入对象示例分享
2014/03/11 PHP
跟我学Laravel之请求与输入
2014/10/15 PHP
自己开发Dojo的建议框架
2008/09/24 Javascript
javascript AutoScroller 函数类
2009/05/29 Javascript
基于jquery扩展漂亮的下拉框可以二次修改
2013/11/19 Javascript
jquery.uploadify插件在chrome浏览器频繁崩溃解决方法
2015/03/01 Javascript
javascript鼠标跟随运动3种效果(眼球效果,苹果菜单,方向跟随)
2016/10/27 Javascript
javascript中的深复制详解及实例分析
2016/12/29 Javascript
node学习记录之搭建web服务器教程
2017/02/16 Javascript
bootstrap modal+gridview实现弹出框效果
2017/08/15 Javascript
浅析JavaScript中的特殊数据类型
2017/12/15 Javascript
JS实现自定义弹窗功能
2018/08/08 Javascript
Three.js实现简单3D房间布局
2018/12/30 Javascript
性能优化篇之Webpack构建速度优化的建议
2019/04/03 Javascript
electron-vue利用webpack打包实现多页面的入口文件问题
2019/05/12 Javascript
vue2.0 实现富文本编辑器功能
2019/05/26 Javascript
vue视频播放暂停代码
2019/11/08 Javascript
taro 实现购物车逻辑的实例代码
2020/06/05 Javascript
mustache.js实现首页元件动态渲染的示例代码
2020/12/28 Javascript
python实现SMTP邮件发送功能
2020/06/16 Python
python多行字符串拼接使用小括号的方法
2020/03/19 Python
基于DataFrame改变列类型的方法
2018/07/25 Python
使用Python向C语言的链接库传递数组、结构体、指针类型的数据
2019/01/29 Python
一款纯css3实现的tab选项卡的实列教程
2014/12/11 HTML / CSS
基于HTML5 WebGL的3D机房的示例
2018/03/16 HTML / CSS
金讯Java笔试题目
2013/06/18 面试题
自我评价个人范文
2013/12/16 职场文书
小学毕业感言500字
2014/02/28 职场文书
质量提升方案
2014/06/16 职场文书
2014公司党员自我评价范文
2014/09/11 职场文书
JavaScript中时间格式化新思路toLocaleString()
2021/11/07 Javascript
Windows 11上手初体验:任务栏和开始菜单等迎来大改
2021/11/21 数码科技
python APScheduler执行定时任务介绍
2022/04/19 Python
python标准库ElementTree处理xml
2022/05/20 Python