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写的Socks5协议代理服务器
Aug 06 Python
Python进行数据提取的方法总结
Aug 22 Python
Python实现一个简单的验证码程序
Nov 03 Python
Python将多个excel表格合并为一个表格
Feb 22 Python
零基础使用Python读写处理Excel表格的方法
May 02 Python
用Python配平化学方程式的方法
Jul 20 Python
Anaconda之conda常用命令介绍(安装、更新、删除)
Oct 06 Python
matplotlib.pyplot画图并导出保存的实例
Dec 07 Python
详解从Django Allauth中进行登录改造小结
Dec 18 Python
Python namedtuple命名元组实现过程解析
Jan 08 Python
Python写出新冠状病毒确诊人数地图的方法
Feb 12 Python
Pytorch中使用ImageFolder读取数据集时忽略特定文件
Mar 23 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设计模式 Observer(观察者模式)
2011/06/26 PHP
PHP最常用的2种设计模式工厂模式和单例模式介绍
2012/08/14 PHP
php开启与关闭错误提示适用于没有修改php.ini的权限
2014/10/16 PHP
PHP使用get_headers函数判断远程文件是否存在的方法
2014/11/28 PHP
php截取视频指定帧为图片
2016/05/16 PHP
laravel项目利用twemproxy部署redis集群的完整步骤
2018/05/11 PHP
PDO::_construct讲解
2019/01/27 PHP
浅谈laravel框架sql中groupBy之后排序的问题
2019/10/17 PHP
js判断变量是否空值的代码
2008/10/26 Javascript
jQuery的$.proxy()应用示例介绍
2014/04/03 Javascript
js实现tab切换效果实例
2015/09/16 Javascript
Hammer.js+轮播原理实现简洁的滑屏功能
2016/02/02 Javascript
jquery仿QQ登录账号选择下拉框效果
2016/03/22 Javascript
vue.js指令v-model使用方法
2017/03/20 Javascript
JavaScript简单计算人的年龄示例
2017/04/15 Javascript
jQuery实现上传图片前预览效果功能
2017/08/03 jQuery
js与jQuery实现获取table中的数据并拼成json字符串操作示例
2018/07/12 jQuery
JS实现多选框的操作
2020/06/24 Javascript
Vue.js桌面端自定义滚动条组件之美化滚动条VScroll
2020/12/01 Vue.js
python获取图片颜色信息的方法
2015/03/18 Python
python自定义解析简单xml格式文件的方法
2015/05/11 Python
python3正则提取字符串里的中文实例
2019/01/31 Python
Pyinstaller打包.py生成.exe的方法和报错总结
2019/04/02 Python
一步步教你用python的scrapy编写一个爬虫
2019/04/17 Python
python 实现让字典的value 成为列表
2019/12/16 Python
python tkinter GUI绘制,以及点击更新显示图片代码
2020/03/14 Python
Python super()方法原理详解
2020/03/31 Python
html5视频媒体标签video的使用方法及完整参数说明详解
2019/09/27 HTML / CSS
美国最大的团购网站:Groupon
2016/07/23 全球购物
韩国知名的家庭购物网站:CJmall
2016/08/01 全球购物
世界上最大的铁人三项商店:Tri UK
2020/11/04 全球购物
晚会邀请函范文
2014/01/24 职场文书
采购意向书范本
2014/03/31 职场文书
飞机制造技术专业求职信
2014/07/27 职场文书
《圆的周长》教学反思
2016/02/17 职场文书
.Net Core导入千万级数据至Mysql的步骤
2021/05/24 MySQL