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 16 Python
Python语言描述最大连续子序列和
Dec 05 Python
python爬取淘宝商品详情页数据
Feb 23 Python
Python实现的远程登录windows系统功能示例
Jun 21 Python
python 2.7 检测一个网页是否能正常访问的方法
Dec 26 Python
Tensorflow中的降维函数tf.reduce_*使用总结
Apr 20 Python
python实现猜单词游戏
May 22 Python
浅谈Python协程
Jun 17 Python
Python使用文件操作实现一个XX信息管理系统的示例
Jul 02 Python
python 生成正态分布数据,并绘图和解析
Dec 21 Python
python爬不同图片分别保存在不同文件夹中的实现
Apr 02 Python
python中的装饰器该如何使用
Jun 18 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导入Excel到MySQL的方法
2011/04/23 PHP
基于header的一些常用指令详解
2013/06/06 PHP
php判断手机访问还是电脑访问示例分享
2014/01/20 PHP
验证手机号码的JS方法分享
2013/09/10 Javascript
javascript实现阻止iOS APP中的链接打开Safari浏览器
2014/06/12 Javascript
一道常被人轻视的web前端常见面试题(JS)
2016/02/15 Javascript
JS函数定义方式的区别介绍
2016/03/22 Javascript
AngularJS 获取ng-repeat动态生成的ng-model值实例详解
2016/11/29 Javascript
简单实现bootstrap导航效果
2017/02/07 Javascript
jQuery Ajax前后端使用JSON进行交互示例
2017/03/17 Javascript
Vue.js项目部署到服务器的详细步骤
2017/07/17 Javascript
jQuery Ajax向服务端传递数组参数值的实例代码
2017/09/03 jQuery
vue.js 嵌套循环、if判断、动态删除的实例
2018/03/07 Javascript
JS实现获取进今年第几天是周几的方法分析
2018/06/27 Javascript
深入解析koa之异步回调处理
2019/06/17 Javascript
Layui给switch添加响应事件的例子
2019/09/03 Javascript
基于vue实现图片验证码倒计时60s功能
2019/12/10 Javascript
Vue实现购物车基本功能
2020/11/08 Javascript
django的登录注册系统的示例代码
2018/05/14 Python
Python中利用xpath解析HTML的方法
2018/05/14 Python
selenium使用chrome浏览器测试(附chromedriver与chrome的对应关系表)
2018/11/29 Python
Python统计时间内的并发数代码实例
2019/12/28 Python
python定义类的简单用法
2020/07/24 Python
Python如何将装饰器定义为类
2020/07/30 Python
详解Django ORM引发的数据库N+1性能问题
2020/10/12 Python
美国在线宠物用品商店:Entirely Pets
2017/01/01 全球购物
库房管理员岗位职责
2014/03/09 职场文书
应届生求职信
2014/05/31 职场文书
工作检讨书怎么写
2014/10/10 职场文书
学习普通话的体会
2014/11/07 职场文书
荆州古城导游词
2015/02/06 职场文书
2015年酒店工作总结范文
2015/04/07 职场文书
辩论赛开场白大全(主持人+辩手)
2015/05/29 职场文书
给校长的建议书作文400字
2015/09/14 职场文书
《棉鞋里的阳光》教学反思
2016/02/20 职场文书
vue项目配置sass及引入外部scss文件
2022/04/14 Vue.js