Python 单例模式(3种方式)

方式一:

# 单例模式:
#     实现目的:实例化多次,得到的实例是同一个,就是同一个对象,同一个名称空间(更加节省空间)

####################################方式一:在类内部定义一个类方法#################################
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):
    def __init__(self,class_name,class_bases,class_dic):
        super(Mymeta,self).__init__(class_name,class_bases,class_dic)

        # obj=self.__new__(self) #造出一个mysql的对象meta
        #         # 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 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__)

原文地址:https://www.cnblogs.com/yangzhizong/p/9315672.html

时间: 2024-08-28 08:57:12

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

单例模式--两种方式

package com.factory; /* * 第一种方式创建单例 */ class OneSingleton{ private static int number =0; //私有属性 private static OneSingleton instance = new OneSingleton(); //OneSingleton的唯一实例 private OneSingleton(){} public static OneSingleton getInstance(){ return i

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

有个excle表格需要做一些过滤然后写入数据库中,但是日期类型的cell取出来是个数字,于是查询了下解决的办法. 基本的代码结构 data = xlrd.open_workbook(EXCEL_PATH) table = data.sheet_by_index(0) lines = table.nrows cols = table.ncols print u'The total line is %s, cols is %s'%(lines, cols) 读取某个单元格: table.cell(x

操作系统,编程语言分类,执行python两种方式,变量,内存管理,定义变量的三个特征

操作系统 1.什么是操作系统 操作系统位于计算机硬件与应用软件之间 是一个协调.管理.控制计算机硬件资源与软件资源的控制程序 2.为何要有操作系统? 1.控制硬件 2.把对硬件的复杂的操作封装成优美简单的接口(文件),给用户或者应用程序去使用 注意:一套完整的计算机系统包含三部分 应用程序:qq,暴风影音,快播 操作系统:windows,linux,unix 计算机硬件 强调: 我们以后开发的都是应用程序 应用程序无法直接操作硬件,但凡要操作硬件,都是调用操作系统的接口 编程语言分类 1.机器语

Python开发实用技巧:获取部分返回值的4种方式

python的函数支持返回多个值.返回多个值时,默认以tuple的方式返回. 例如,下面两个函数的定义是完全等价的. 1 def f(): 2 return 1,2 3 4 def f(): 5 return (1,2) 如果将函数调用的返回值赋值给对应个数的变量,它会一一对应的赋值,这很容易理解.下面是等价的: 1 a, b = f() # a=1, b=2 2 (a, b) = f() 如果赋值给一个变量,将会把整个元组赋值给变量.下面是等价的,a表示整个元组(1,2): 1 a = f()

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

python实现单例模式的三种方式及相关知识解释 模块模式 装饰器模式 父类重写new继承 单例模式作为最常用的设计模式,在面试中很可能遇到要求手写.从最近的学习python的经验而言,singleton实现的四种方法都是python的重要特征,反过来也刚好是几种特征的最佳实现.(比如你平常开发中很难遇到几个需要写元类的地方)如果不能随手写出某种实现,说明你对于那种实现的概念还没有完全掌握.最近场通过写装饰器模式的singleton来复习装饰器概念. 1. module实现 #模块实现 from

python全栈开发【补充】单例模式的四种方式

一.什么是单例模式 保证一个类只有一个实例,并提供一个访问它的全局访问点 二.优点 对唯一实例的受控访问 单利相当于全局变量,但防止了命名空间被污染 与单利模式功能相似的概念:全局变量.静态变量(方法) 试问?为什么用单例模式,不用全局变量呢? 答.全局变量可能会有名称空间的干扰,如果有重名的可能会被覆盖 三.使用场景 当类只有一个实例而且客户可以从一个众所周知的访问点访问它时 比如:数据库链接.Socket创建链接 四.单例模式的四种实现方式 # 1.模块导入的形式 s1.py class F

单例模式创建的三种方式

一.单例模式的好处 1.对于频繁使用的对象,可以省略new操作花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销: 2.由于new操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻GC压力,缩短GC停顿时间. 二.创建方式 1)饿汉式 1 public class Singleton { 2     private Singleton(){ 3         System.out.println("Singleton is create"); 4     } 5 

python中字符串链接的七种方式

一. str1+str2 string类型 '+'号连接 >>> str1="one" >>> str2="two" >>> str1+str2 'onetwo' >>>注意:该方式性能较差,因为python中字符串是不可变的类型,使用 + 连接两个字符串时会生成一个新的字符串,生成新的字符串就需要重新申请内存,当连续相加的字符串很多时(a+b+c+d+e+f+...) ,效率低下就是必然的了例

[Python] 发送email的几种方式

python发送email还是比较简单的,可以通过登录邮件服务来发送,linux下也可以使用调用sendmail命令来发送,还可以使用本地或者是远程的smtp服务来发送邮件,不管是单个,群发,还是抄送都比较容易实现. 先把几个最简单的发送邮件方式记录下,像html邮件,附件等也是支持的,需要时查文档即可 1 登录邮件服务 #!/usr/bin/env python # -*- coding: utf-8 -*- #python2.7x #send_simple_email_by_account.

python实现堆排序的三种方式

# -*- coding: utf-8 -*- """ Created on Fri May 16 14:57:50 2014 @author: lifeix """ import heapq #堆排序 #第一种实现 def Heapify(a, start, end): left = 0 right = 0 maxv = 0 left = start * 2 right = start * 2 + 1 while left <= end: