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 相关文章推荐
wxPython窗口中文乱码解决方法
Oct 11 Python
Python使用cx_Oracle模块将oracle中数据导出到csv文件的方法
May 16 Python
Python如何为图片添加水印
Nov 25 Python
Django使用paginator插件实现翻页功能的实例
Oct 24 Python
pycharm在调试python时执行其他语句的方法
Nov 29 Python
Python中的heapq模块源码详析
Jan 08 Python
Python爬取数据保存为Json格式的代码示例
Apr 09 Python
Python如何调用外部系统命令
Aug 07 Python
深入学习python多线程与GIL
Aug 26 Python
Python Sympy计算梯度、散度和旋度的实例
Dec 06 Python
pycharm不以pytest方式运行,想要切换回普通模式运行的操作
Sep 01 Python
opencv检测动态物体的实现
Jul 21 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
正则表达式语法
2006/10/09 Javascript
PHP获取不了React Native Fecth参数的解决办法
2016/08/26 PHP
使用正则去除php代码中的注释方法
2016/11/03 PHP
浅谈PHP中的面向对象OOP中的魔术方法
2017/06/12 PHP
如何修改Laravel中url()函数生成URL的根地址
2017/08/11 PHP
在JavaScript中实现类的方式探讨
2013/08/28 Javascript
js函数名与form表单元素同名冲突的问题
2014/03/07 Javascript
Angularjs基础知识及示例汇总
2015/01/22 Javascript
jQuery实现复选框批量选择与反选的方法
2015/06/17 Javascript
nodejs创建web服务器之hello world程序
2015/08/20 NodeJs
jQuery on()方法示例及jquery on()方法的优点
2015/08/27 Javascript
Bootstrap3制作搜索框样式的方法
2016/07/11 Javascript
JS简单判断字符在另一个字符串中出现次数的2种常用方法
2017/04/20 Javascript
微信小程序图片横向左右滑动案例
2017/05/19 Javascript
vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)
2018/10/24 Javascript
微信小程序学习笔记之跳转页面、传递参数获得数据操作图文详解
2019/03/28 Javascript
javascript面向对象三大特征之封装实例详解
2019/07/24 Javascript
高性能js数组去重(12种方法,史上最全)
2019/12/21 Javascript
Node 模块原理与用法详解
2020/05/13 Javascript
[01:12]DOTA2 2015年秋季互动指南
2015/11/10 DOTA
python常用web框架简单性能测试结果分享(包含django、flask、bottle、tornado)
2014/08/25 Python
Python使用re模块实现信息筛选的方法
2018/04/29 Python
python3读取图片并灰度化图片的四种方法(OpenCV、PIL.Image、TensorFlow方法)总结
2019/07/04 Python
Python使用tkinter模块实现推箱子游戏
2019/10/08 Python
Python日志处理模块logging用法解析
2020/05/19 Python
萨克斯第五大道英国:Saks Fifth Avenue英国
2019/04/01 全球购物
美国相机和电子产品零售商:Beach Camera
2020/11/26 全球购物
泰国排名第一的家居用品中心:HomePro
2020/11/18 全球购物
店长助理岗位职责
2013/12/13 职场文书
应届毕业生个人求职自荐信
2014/01/06 职场文书
小学五年级学生评语
2014/04/22 职场文书
小学优秀班主任材料
2014/12/17 职场文书
辩论赛主持人开场白
2015/05/29 职场文书
2019最新婚庆对联集锦!
2019/07/10 职场文书
golang 实现时间戳和时间的转化
2021/05/07 Golang
pytorch 使用半精度模型部署的操作
2021/05/24 Python