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 相关文章推荐
MySQLdb ImportError: libmysqlclient.so.18解决方法
Aug 21 Python
详解Python命令行解析工具Argparse
Apr 20 Python
Python异常的检测和处理方法
Oct 26 Python
Python实现程序判断季节的代码示例
Jan 28 Python
pandas 使用均值填充缺失值列的小技巧分享
Jul 04 Python
python字典的setdefault的巧妙用法
Aug 07 Python
Python性能分析工具Profile使用实例
Nov 19 Python
利用matplotlib实现根据实时数据动态更新图形
Dec 13 Python
kafka监控获取指定topic的消息总量示例
Dec 23 Python
Python tkinter常用操作代码实例
Jan 03 Python
python GUI库图形界面开发之PyQt5下拉列表框控件QComboBox详细使用方法与实例
Feb 27 Python
浅谈TensorFlow中读取图像数据的三种方式
Jun 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
PHP 实现多服务器共享 SESSION 数据
2009/08/15 PHP
PHP访问MYSQL数据库封装类(附函数说明)
2010/12/04 PHP
php中{}大括号是什么意思
2013/12/01 PHP
CI框架支持$_GET的两种实现方法
2016/05/18 PHP
php生成mysql的数据字典
2016/07/07 PHP
使用PHP连接多种数据库的实现代码(mysql,access,sqlserver,Oracle)
2016/12/21 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
JavaScript中的方法重载实例
2015/03/16 Javascript
yui3的AOP(面向切面编程)和OOP(面向对象编程)
2015/05/01 Javascript
微信小程序开发入门基础教程
2017/04/19 Javascript
jquery实现企业定位式导航效果
2018/01/01 jQuery
JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法示例
2018/07/27 Javascript
vue2.0$nextTick监听数据渲染完成之后的回调函数方法
2018/09/11 Javascript
微信小程序在text文本实现多种字体样式
2019/11/08 Javascript
js模拟实现烟花特效
2020/03/10 Javascript
分析Python编程时利用wxPython来支持多线程的方法
2015/04/07 Python
Python 获取当前所在目录的方法详解
2017/08/02 Python
numpy排序与集合运算用法示例
2017/12/15 Python
解决Python requests库编码 socks5代理的问题
2018/05/07 Python
Python构建图像分类识别器的方法
2019/01/12 Python
python-序列解包(对可迭代元素的快速取值方法)
2019/08/24 Python
python随机生成大小写字母数字混合密码(仅20行代码)
2020/02/01 Python
python爬虫scrapy框架的梨视频案例解析
2021/02/20 Python
浅析两列自适应布局的3种思路
2016/05/03 HTML / CSS
移动端适配 使px自动转换rem
2019/08/26 HTML / CSS
MAC彩妆澳洲官网:M·A·C AU
2021/01/17 全球购物
最新离婚协议书范本
2014/08/19 职场文书
弄虚作假心得体会
2014/09/10 职场文书
2014党的群众路线教育实践活动总结报告
2014/10/31 职场文书
论群众路线学习心得体会
2014/10/31 职场文书
领导新年致辞2016
2015/07/29 职场文书
浅谈MySQL函数
2021/10/05 MySQL
Python 中 Shutil 模块详情
2021/11/11 Python
深入理解go缓存库freecache的使用
2022/02/15 Golang
CSS实现渐变色边框(Gradient borders)的5种方法
2022/03/25 HTML / CSS
MySQL GTID复制的具体使用
2022/05/20 MySQL