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基础教程之基本数据类型和变量声明介绍
Aug 29 Python
利用Python和OpenCV库将URL转换为OpenCV格式的方法
Mar 27 Python
使用IronPython把Python脚本集成到.NET程序中的教程
Mar 31 Python
详解Python中的文件操作
Aug 28 Python
Python判断某个用户对某个文件的权限
Oct 13 Python
Python3.x对JSON的一些操作示例
Sep 01 Python
git进行版本控制心得详谈
Dec 10 Python
python去掉空白行的多种实现代码
Mar 19 Python
Python实现的基于优先等级分配糖果问题算法示例
Apr 25 Python
Python3中关于cookie的创建与保存
Oct 21 Python
Python实现bilibili时间长度查询的示例代码
Jan 14 Python
教你用Python爬取英雄联盟皮肤原画
Jun 13 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文件怎么打开 如何执行php文件
2011/12/21 PHP
深入了解PHP中的Array数组和foreach
2016/11/06 PHP
php数组遍历类与用法示例
2019/05/24 PHP
基于jQuery的可用于选项卡及幻灯的切换插件
2011/03/28 Javascript
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
解决javascript:window.close()在chrome,Firefox下失效的问题
2013/05/07 Javascript
jquery提交form表单时禁止重复提交的方法
2014/02/13 Javascript
js仿苹果iwatch外观的计时器代码分享
2015/08/26 Javascript
实例讲解jquery中mouseleave和mouseout的区别
2016/02/17 Javascript
jQuery实现表格与ckeckbox的全选与单选功能
2016/11/24 Javascript
vuejs2.0运用原生js实现简单的拖拽元素功能示例
2017/02/24 Javascript
利用js查找数组中指定元素并返回该元素的所有索引示例
2017/03/29 Javascript
JS判断两个对象内容是否相等的方法示例
2017/04/10 Javascript
Nodejs 和Session 原理及实战技巧小结
2017/08/25 NodeJs
JavaScript运行原理分析
2018/02/09 Javascript
使用json-server简单完成CRUD模拟后台数据的方法
2018/07/12 Javascript
swiper在angularjs中使用循环轮播失效的解决方法
2018/09/27 Javascript
小程序日历控件使用方法详解
2018/12/29 Javascript
jQuery Ajax async=&gt;false异步改为同步时,解决导致浏览器假死的问题
2019/07/22 jQuery
layui-table对返回的数据进行转变显示的实例
2019/09/04 Javascript
AutoJs实现刷宝短视频的思路详解
2020/05/22 Javascript
wxpython 学习笔记 第一天
2009/02/09 Python
python使用BeautifulSoup分析网页信息的方法
2015/04/04 Python
Python 自动刷博客浏览量实例代码
2017/06/14 Python
python itchat实现微信好友头像拼接图的示例代码
2017/08/14 Python
在Python中实现替换字符串中的子串的示例
2018/10/31 Python
Python greenlet和gevent使用代码示例解析
2020/04/01 Python
20行Python代码实现视频字符化功能
2020/04/13 Python
如何用Python 加密文件
2020/09/10 Python
The Hut美国/加拿大:英国领先的豪华在线百货商店
2019/03/26 全球购物
韩语专业本科生求职信
2013/10/01 职场文书
菜篮子工程实施方案
2014/03/08 职场文书
公司保密承诺书
2014/03/27 职场文书
春节联欢会策划方案
2014/05/16 职场文书
庆祝儿童节标语
2014/10/09 职场文书
实习计划书范文
2015/01/16 职场文书