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 相关文章推荐
跟老齐学Python之有容乃大的list(1)
Sep 14 Python
浅析Python中的多条件排序实现
Jun 07 Python
ubuntu安装mysql pycharm sublime
Feb 20 Python
python3爬取各类天气信息
Feb 24 Python
Pycharm 设置自定义背景颜色的图文教程
May 23 Python
python实现坦克大战游戏 附详细注释
Mar 27 Python
Python进阶:生成器 懒人版本的迭代器详解
Jun 29 Python
详解Django-channels 实现WebSocket实例
Aug 22 Python
如何定义TensorFlow输入节点
Jan 23 Python
Python 实现日志同时输出到屏幕和文件
Feb 19 Python
基于jupyter代码无法在pycharm中运行的解决方法
Apr 21 Python
Python基础学习之奇异的GUI对话框
May 27 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数组传递是值传递而非引用传递概念纠正
2013/01/31 PHP
优化PHP代码技巧的小结
2013/06/02 PHP
php实现的中文分词类完整实例
2017/02/06 PHP
Javascript 异步加载详解(浏览器在javascript的加载方式)
2012/05/20 Javascript
js简单的表格添加行和删除行操作示例
2014/03/31 Javascript
浅谈jquery.fn.extend与jquery.extend区别
2015/07/13 Javascript
JS调用Android、Ios原生控件
2017/01/06 Javascript
正则 js分转元带千分符号详解
2017/03/08 Javascript
微信小程序中用WebStorm使用LESS
2017/03/08 Javascript
JQuery 封装 Ajax 常用方法(推荐)
2017/05/21 jQuery
Node.js模拟发起http请求从异步转同步的5种用法
2018/09/26 Javascript
webpack打包非模块化js的方法
2018/10/24 Javascript
vue3 源码解读之 time slicing的使用方法
2019/10/31 Javascript
[01:12:40]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第三场 1月25日
2021/03/11 DOTA
python冒泡排序算法的实现代码
2013/11/21 Python
Django中模型Model添加JSON类型字段的方法
2015/06/17 Python
Python贪吃蛇游戏编写代码
2020/10/26 Python
python中关于for循环的碎碎念
2017/06/30 Python
详解Python在七牛云平台的应用(一)
2017/12/05 Python
Python数据分析库pandas基本操作方法
2018/04/08 Python
pandas修改DataFrame列名的方法
2018/04/08 Python
python使用 request 发送表单数据操作示例
2019/09/25 Python
Python 如何优雅的将数字转化为时间格式的方法
2019/09/26 Python
Python函数参数类型及排序原理总结
2019/12/19 Python
解决Python pip 自动更新升级失败的问题
2020/02/21 Python
Python datetime模块使用方法小结
2020/06/18 Python
python--shutil移动文件到另一个路径的操作
2020/07/13 Python
行政专员求职信范文
2014/05/03 职场文书
物业管理委托协议(2篇)
2014/09/23 职场文书
领导班子专题民主生活会情况想汇报
2014/09/30 职场文书
2014年英语教师工作总结
2014/12/03 职场文书
幼儿园教师自我评价
2015/03/04 职场文书
爱的教育读书笔记
2015/06/26 职场文书
导游词之南昌滕王阁
2019/11/29 职场文书
浅谈@Value和@Bean的执行顺序问题
2021/06/16 Java/Android
Python OpenGL基本配置方式
2022/05/20 Python