方式一:

# 单例模式:
# 实现目的:实例化多次,得到的实例是同一个,就是同一个对象,同一个名称空间(更加节省空间) ####################################方式一:在类内部定义一个类方法#################################
import settings class Mysql:
__instance=None #定义一个变量,来接收实例化对象,方便下面做判断
def __init__(self,ip,port):
self.ip=ip
self.port=port #
@classmethod #做成类方法 #绑定给Mysql类去直接调用实例化
def from_conf(cls):
#目的是要调取mysql这个类通过从配置文件读取IP、端口参数,完成调用init方法,拿到一个实例化init方法的对象
# mysql(settings.IP,settings.PORT) #如果是这样每次,实例化出的对象,都是不同的名称空间,但是数据是同一份
# return cls(settings.IP,settings.PORT) #cls(ip,port) 就是调用init方法 #演变最终版:思考可以统一定义一个初始变量__instance=None,将第一次实例的对象传给他,有每次外面再访问就直接
if cls.__instance is None:
cls.__instance=cls(settings.IP,settings.PORT)
return cls.__instance #之前版本:
# p1=Mysql.from_conf()
# print(p1) #<__main__.Mysql object at 0x02BE82B0> #数据是同一份,但每次实例化,指向的都是不同的内存地址
# p2=Mysql.from_conf()
# print(p2) #<__main__.Mysql object at 0x02C1AB90> #这样写就完美的实现了隔离:
#升级版本后,可以实现,访问存的东西一样的,可以指向同一个内存空间
obj=Mysql.from_conf()
print(obj.__dict__) #也可以传入新的参数,另外新造一个名称空间
obj2=Mysql('3.3.3.3',8888)
print(obj2.__dict__)

方式二:

#方式二:装饰器
import settings def singleton(cls):
__instance=cls(settings.IP,settings.PORT) #给Mysql的init方法传参,实例化得到一个对象,__instance
def wrapper(*args,**kwargs): #判断外面调用时,是否有传值进来
if len(args) == 0 and len(kwargs)== 0:
return __instance #用户没有传传参,意思直接返回默认settings的值
return cls(*args,**kwargs) #否则会创建新的值
return wrapper @singleton
class Mysql: ##Mysql=singleton(Mysql) #Mysql=wrapper
def __init__(self,ip,port):
self.ip=ip
self.port=port
def aa(self):
print('IP地址:%s 端口:%s'%(self.ip,self.port)) #实现的结果是:想要实现的是mysql不传参数,默认指向同一个实例
#没有传参数的调用:保证每次实例化得到的是同一个内存地址
obj1=Mysql() #wrapper()
obj2=Mysql() #wrapper()
print(obj1.__dict__,id(obj)) #{'ip': '1.1.1.1', 'port': 3306} 45554896
print(obj2.__dict__,id(obj)) #{'ip': '1.1.1.1', 'port': 3306} 45554896
#有传参的情况下,创建新的
obj2=Mysql('2.2.2.2',666)
print(obj2.__dict__)

方式三:

方式三:自定义元类
#自定义元类控制类的调用过程,即类的实例化:__call__
import settings
class Mymeta(type): #init在定义类时就已经建好了
def __init__(self,class_name,class_bases,class_dic): #造Mysql空对象,调类中init方法,继承父类,造一个空对象
super(Mymeta,self).__init__(class_name,class_bases,class_dic) # obj=self.__new__(self) #造出一个mysql的空对象
# # self.__init__(obj,settings.IP,settings.PORT) #w从配置文件中加载配置完成Mysql对象的初始化
# # self.__instance=obj #赋值操作
     #
self.__instance=self.__new__(self) #先造一个空对象 __instance
self.__init__(self.__instance,settings.IP,settings.PORT) #为空的对象初始化独有的属性
print(self.__instance.__dict__) #这一步刚刚造完类,还没运行代码就已经造好了一个空对象,保存到类属性中 def __call__(self, *args, **kwargs): #在调用类时才运行
if len(args)==0 and len(kwargs)==0:
      #思考应该 return 一个已经创建好的Mysql的对象
      #因为call方法只有在调用时才触发,但是要在调用前就应该创建好一个Mysql的对象
return self.__instance ##如果没有会直接传入
obj=self.__new__(self)
self.__init__(obj,*args,**kwargs)
return obj class Mysql(object,metaclass=Mymeta):
def __init__(self,ip,port):
self.ip=ip
self.port=port #拿到的是同一个内存空间地址
obj=Mysql()
obj1=Mysql()
obj2=Mysql()
print(obj)
print(obj1)
print(obj2)
#拿到是单独的内存地址
obj2=Mysql('3.3.3.3',8888)
print(obj2.__dict__) 注意:
1.Mysql的调用时才运行__call__ (控制的是类Mysql的调用过程,就是类mysql的实例化过程)
2.__init__(控制类Mysql这个对象的产生过程,就是类Mymeta的实例化过程) 

Python 单例模式(3种方式)的更多相关文章

  1. python学习-- 两种方式查看自己的Django版本

    [第一种方式] Windows系统下 按住Windows按键 + R 进入搜索:搜索CMD进入控制台:输入Python进入Python解释器 Linux系统下 直接使用终端调用Python解释器 接下 ...

  2. bat批处理执行python 的几种方式

    第一种方式:@echo off C: cd C:\Users\administrator\Desktopstart python apidemo.py exit第二种方式: start cmd /K ...

  3. Python的6种方式实现单例模式

    单例模式是一个软件的设计模式,为了保证一个类,无论调用多少次产生的实例对象,都是指向同一个内存地址,仅仅只有一个实例(只有一个对象). 实现单例模式的手段有很多种,但总的原则是保证一个类只要实例化一个 ...

  4. Python单例模式的实现方式

    一.单例类 单例模式(Singleton Pattern)是 Python 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类 ...

  5. 四、执行Python的两种方式

    第一种 交互式 ,在cmd中运行 · jupyter对这一种进行了封装 优点: 直接输出结果 缺点: 无法保存 第二种 命令式,通过cmd中输入python3文本 txt文件可以,py文件也可以,命令 ...

  6. PyCharm 中文教程 01:运行 Python 的四种方式

    <PyCharm 中文指南>在线阅读: http://pycharm.iswbm.com/ Github 项目主页: https://github.com/iswbm/pych... 1. ...

  7. 执行python解释器的两种方式

    执行python解释器的两种方式 1.交互式 python是高级语言,是解释型语言,逐行翻译,写一句翻译一句 print ('hello world') 2.命令行式 python和python解释器 ...

  8. [Python]xlrd 读取excel 日期类型2种方式

    有个excle表格须要做一些过滤然后写入数据库中,可是日期类型的cell取出来是个数字,于是查询了下解决的办法. 主要的代码结构 data = xlrd.open_workbook(EXCEL_PAT ...

  9. python实现单例模式的三种方式及相关知识解释

    python实现单例模式的三种方式及相关知识解释 模块模式 装饰器模式 父类重写new继承 单例模式作为最常用的设计模式,在面试中很可能遇到要求手写.从最近的学习python的经验而言,singlet ...

  10. Python之面向对象之单例模式的四种方式

    一.内容 保证一个类只有一个实例,并提供一个访问它的全局访问点 二.角色 单利 三.使用场景 当类只有一个实例而且客户可以从一个众所周知的访问点访问它时 比如:数据库链接.Socket创建链接 四.优 ...

随机推荐

  1. EasyUI:Easyui parser的用法

    Easyui的渲染机制是个比较坑的事情,在项目开发中,遇到需要等其渲染完成后处理一些事情,比如为联动的下拉框选中默认值,为某些表单元素自动填充值等!这就需要用到Easyui parser解析器了.官方 ...

  2. 转 winfrom如何通过http来进行通信,并且通过传递json格式的数据可接受json格式的数据

    string username = this.textBox1.Text; string password = this.textBox2.Text; string AA = HttpUtility. ...

  3. python 之正则表达式

    一.正则表达式 首先,我们需要感性的了解下什么是正则表达式,简单的是说“正则表达式”就是一个“表达式”,更准确定义是:“用一个简洁的方法来实现对“一组字符串”的表达式. 最终目的就是实现“一行胜千言” ...

  4. javaSe-hashMap

    package com.java.chap08.sec05; public class Student { private String name; private Integer age; publ ...

  5. 【Python图像特征的音乐序列生成】生成伴奏旋律(附部分代码)

    做了半天做的都是一些细枝末节的东西,嗨呀. 伴奏旋律是Ukulele和弦,MIDI发音乐器是Guitar.在弹唱的时候,Ukulele和弦就是伴奏. 我们以创建<成都>伴奏为例: 节奏型: ...

  6. 【Python图像特征的音乐序列生成】图像特征在旋律生成中有什么用

    jishude 首先援引一个资料网页:http://www.cosmosshadow.com/ml/%E5%BA%94%E7%94%A8/2016/03/01/%E9%9F%B3%E4%B9%90%E ...

  7. JavaScript 获取对象中第一个属性

    使用 Object.keys(object) 可以取出属性名为数组,但会打乱顺序 严格意义上对象中是只有映射关系而没有顺序的,但是在存储结构里是有顺序的,如果想获取存储结构里的第一个属性可以使用for ...

  8. “CTL_CODE”未定义

    C4013 “CTL_CODE”未定义:假设外部返回 int 要加入 #include<winioctl.h> 并且要放在#include<windows.h>的后面

  9. java基础—方法重载(overload)

    一.方法的重载 方法名一样,但参数不一样,这就是重载(overload). 所谓的参数不一样,主要有两点:第一是参数的个数不一样,第二是参数的类型不一样.只要这两方面有其中的一方面不一样就可以构成方法 ...

  10. 字符串 -----JavaScript

    本文摘要:http://www.liaoxuefeng.com/ JavaScript的字符串就是用''或""括起来的字符表示. 如果'本身也是一个字符,那就可以用"&q ...