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自动化工具日志查询分析脚本代码实现
Nov 26 Python
Python字符串详细介绍
May 09 Python
PyQt5利用QPainter绘制各种图形的实例
Oct 19 Python
Python实现嵌套列表及字典并按某一元素去重复功能示例
Nov 30 Python
django rest framework 数据的查找、过滤、排序的示例
Jun 25 Python
PyCharm搭建Spark开发环境实现第一个pyspark程序
Jun 13 Python
Python3如何判断三角形的类型
Apr 12 Python
新建文件时Pycharm中自动设置头部模板信息的方法
Apr 17 Python
使用matplotlib动态刷新指定曲线实例
Apr 23 Python
手把手教你将Flask应用封装成Docker服务的实现
Aug 19 Python
Django配置Bootstrap, js实现过程详解
Oct 13 Python
Django数据模型中on_delete使用详解
Nov 30 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
用js进行url编码后用php反解以及用php实现js的escape功能函数总结
2010/02/08 PHP
PHP获取当前日期和时间及格式化方法参数
2015/05/11 PHP
PHP商品秒杀问题解决方案实例详解【mysql与redis】
2019/07/22 PHP
JQuery AJAX实现目录浏览与编辑的代码
2008/10/21 Javascript
Jquery中的CheckBox、RadioButton、DropDownList的取值赋值实现代码
2011/10/12 Javascript
深入理解JavaScript系列(12) 变量对象(Variable Object)
2012/01/16 Javascript
javascript工具库代码
2012/03/29 Javascript
jQuery图片的展开和收缩实现代码
2013/04/16 Javascript
5分钟理解JavaScript中this用法分享
2013/11/09 Javascript
jQuery动态添加、删除元素的方法
2014/01/09 Javascript
jQuery中empty()方法用法实例
2015/01/16 Javascript
JQuery中serialize() 序列化
2015/03/13 Javascript
jquery实现图片随机排列的方法
2015/05/04 Javascript
使用JavaScript制作一个简单的计数器的方法
2015/07/07 Javascript
jQuery实现的多张图无缝滚动效果【测试可用】
2016/09/12 Javascript
js时间控件只显示年月
2017/01/08 Javascript
JS实现二叉查找树的建立以及一些遍历方法实现
2017/04/17 Javascript
微信小程序实现日历功能
2018/11/27 Javascript
原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作
2019/02/27 jQuery
vue自定义指令directive的使用方法
2019/04/07 Javascript
前端路由&amp;webpack基础配置详解
2019/06/10 Javascript
vue实现图片上传功能
2020/05/28 Javascript
[01:00:30]完美世界DOTA2联赛循环赛 Inki vs Matador BO2第二场 10.31
2020/11/02 DOTA
python实现将内容分行输出
2015/11/05 Python
tensorflow: variable的值与variable.read_value()的值区别详解
2018/07/30 Python
Scrapy-Redis结合POST请求获取数据的方法示例
2019/05/07 Python
对Python中一维向量和一维向量转置相乘的方法详解
2019/08/26 Python
TensorFlow2.X使用图片制作简单的数据集训练模型
2020/04/08 Python
详解移动端HTML5音频与视频问题及解决方案
2018/08/22 HTML / CSS
BudgetAir印度:预订航班、酒店和汽车租赁
2019/07/07 全球购物
C#中的验证控件有几种
2014/03/08 面试题
中秋节主持词
2014/04/02 职场文书
党员批评与自我批评发言材料
2014/10/14 职场文书
公司年会晚会开幕词
2019/04/02 职场文书
详解CSS3.0(Cascading Style Sheet) 层叠级联样式表
2021/07/16 HTML / CSS
CSS三大特性继承性、层叠性和优先级详解
2022/01/18 HTML / CSS