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处理图片之PIL模块简单使用方法
May 11 Python
Python常用的文件及文件路径、目录操作方法汇总介绍
May 21 Python
CentOS6.5设置Django开发环境
Oct 13 Python
Python实现的视频播放器功能完整示例
Feb 01 Python
python实现批量按比例缩放图片效果
Mar 30 Python
利用numpy和pandas处理csv文件中的时间方法
Apr 19 Python
通过python将大量文件按修改时间分类的方法
Oct 17 Python
使用python批量化音乐文件格式转换的实例
Jan 09 Python
对Django 中request.get和request.post的区别详解
Aug 12 Python
使用python实现希尔、计数、基数基础排序的代码
Dec 25 Python
python 遍历磁盘目录的三种方法
Apr 02 Python
粗暴解决CUDA out of memory的问题
May 22 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 array_intersect比array_diff快(附详细的使用说明)
2011/07/03 PHP
php下载文件源代码(强制任意文件格式下载)
2014/05/09 PHP
ThinkPHP字符串函数及常用函数汇总
2014/07/18 PHP
php传值赋值和传地址赋值用法实例分析
2015/06/20 PHP
PHP实现的多文件上传类及用法示例
2016/05/06 PHP
php利用ffmpeg提取视频中音频与视频画面的方法详解
2017/06/07 PHP
PHP的curl函数的用法总结
2019/02/14 PHP
PHP开发API接口签名生成及验证操作示例
2020/05/27 PHP
js时间戳格式化成日期格式的多种方法
2013/11/11 Javascript
三种方式获取XMLHttpRequest对象
2014/04/21 Javascript
JS简单实现城市二级联动选择插件的方法
2015/08/19 Javascript
基于HTML模板和JSON数据的JavaScript交互(移动端)
2016/04/06 Javascript
jQuery实现移动端Tab选项卡效果
2017/03/15 Javascript
学习使用Bootstrap栅格系统
2017/05/11 Javascript
浅谈Koa服务限流方法实践
2017/10/23 Javascript
layui实现三级联动效果
2019/07/26 Javascript
[08:47]2018国际邀请赛 OG战队举杯时刻
2018/08/29 DOTA
Python获取邮件地址的方法
2015/07/10 Python
Python编程中字符串和列表的基本知识讲解
2015/10/14 Python
Python3.2模拟实现webqq登录
2016/02/15 Python
python用户管理系统的实例讲解
2017/12/23 Python
Python+OpenCV实现车牌字符分割和识别
2018/03/31 Python
Python批处理更改文件名os.rename的方法
2018/10/26 Python
实例详解Matlab 与 Python 的区别
2019/04/26 Python
Python编写带选项的命令行程序方法
2019/08/13 Python
python3 map函数和filter函数详解
2019/08/26 Python
python生成随机红包的实例写法
2019/09/02 Python
将python2.7添加进64位系统的注册表方式
2019/11/20 Python
Python控制台输出时刷新当前行内容而不是输出新行的实现
2020/02/21 Python
法国美发器材和产品购物网站:Beauty Coiffure
2016/12/05 全球购物
BASIC HOUSE官方旗舰店:韩国著名的服装品牌
2018/09/27 全球购物
下述程序的作用是计算机数组中的最大元素值及其下标
2012/11/26 面试题
医院护理人员的自我评价分享
2013/10/04 职场文书
毕业论文评语大全
2014/04/29 职场文书
园林专业毕业生自荐信
2014/07/04 职场文书
少年雷锋观后感
2015/06/10 职场文书