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编程中的字符串
Oct 14 Python
itchat和matplotlib的结合使用爬取微信信息的实例
Aug 25 Python
Python网络爬虫与信息提取(实例讲解)
Aug 29 Python
django输出html内容的实例
May 27 Python
在Python中使用gRPC的方法示例
Aug 08 Python
对Python生成器、装饰器、递归的使用详解
Jul 19 Python
python+logging+yaml实现日志分割
Jul 22 Python
python 动态迁移solr数据过程解析
Sep 04 Python
Django视图扩展类知识点详解
Oct 25 Python
python3常用的数据清洗方法(小结)
Oct 31 Python
xadmin使用formfield_for_dbfield函数过滤下拉表单实例
Apr 07 Python
python图片验证码识别最新模块muggle_ocr的示例代码
Jul 03 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内存缓存Memcached类实例
2014/12/08 PHP
php compact 通过变量创建数组
2016/11/15 PHP
PHP读取CSV大文件导入数据库的实例
2017/07/24 PHP
PHP APP微信提现接口代码
2018/09/30 PHP
js 判断checkbox是否选中的操作方法
2012/11/09 Javascript
javascript截取字符串(通过substring实现并支持中英文混合)
2013/06/24 Javascript
jquery showModelDialog的使用方法示例详解
2013/11/19 Javascript
javascript常用方法汇总
2014/12/02 Javascript
三种AngularJS中获取数据源的方式
2016/02/02 Javascript
Webstorm2016使用技巧(SVN插件使用)
2018/10/29 Javascript
elementUI 设置input的只读或禁用的方法
2018/10/30 Javascript
JavaScript学习笔记之基于定时器实现图片无缝滚动功能详解
2019/01/09 Javascript
微信公众号中的JSSDK接入及invalid signature等常见错误问题分析(全面解析)
2020/04/11 Javascript
python文件读写操作与linux shell变量命令交互执行的方法
2015/01/14 Python
python通过pil为png图片填充上背景颜色的方法
2015/03/17 Python
在Python上基于Markov链生成伪随机文本的教程
2015/04/17 Python
python获取外网ip地址的方法总结
2015/07/02 Python
Python中如何获取类属性的列表
2016/12/26 Python
使用 Python 实现微信公众号粉丝迁移流程
2018/01/03 Python
linux安装Python3.4.2的操作方法
2018/09/28 Python
python进阶之多线程对同一个全局变量的处理方法
2018/11/09 Python
Python定义一个Actor任务
2020/07/29 Python
如何查看浏览器对html5的支持情况
2020/12/15 HTML / CSS
Clarks鞋法国官方网站:英国其乐鞋品牌
2018/02/11 全球购物
索引覆盖(Index Covering)查询含义
2012/02/18 面试题
毕业生个人的自我评价优秀范文
2013/10/03 职场文书
毕业生求职信的经典写法
2014/01/31 职场文书
海飞丝的广告词
2014/03/20 职场文书
机关搬迁方案
2014/05/18 职场文书
2014年乡镇工会工作总结
2014/12/02 职场文书
自主招生自荐信怎么写
2015/03/24 职场文书
汽车销售员工作总结
2015/08/12 职场文书
会计继续教育培训心得体会
2016/01/19 职场文书
初三化学教学反思
2016/02/22 职场文书
小学生六年级作文之关于感恩
2019/08/16 职场文书
深度学习详解之初试机器学习
2021/04/14 Python