首页 > 其他 > 详细

实现单例的四种方法

时间:2019-02-15 17:41:59      阅读:145      评论:0      收藏:0      [点我收藏+]

1. 储备知识

# 储备知识
#4 、自定义元类:
class Mymeta(type):
    # 来控制类Foo的创建
    def __init__(self,class_name,class_bases,class_dic): #self=Foo

        if not class_name.istitle():
            raise TypeError(类名的首字母必须大写傻叉)

        if not class_dic.get(__doc__):
            raise TypeError(类中必须写好文档注释,大傻叉)

        super(Mymeta,self).__init__(class_name,class_bases,class_dic)
#
    # 控制类Foo的调用过程,即控制实例化Foo的过程
    def __call__(self, *args, **kwargs): #self=Foo,args=(1111,) kwargs={}

        #1 造一个空对象obj
        obj=object.__new__(self)

        #2、调用Foo.__init__,将obj连同调用Foo括号内的参数一同传给__init__
        self.__init__(obj,*args,**kwargs)

        return obj

·····························

# 单例:所有实例化出来的对象都是同一个

# 所有的配置信息放在一个类中,拿配置文件就实例化类的对象就行
# (问题是每次拿到的对象虽然一样,但内存地址不同,就用到了单例)

# 第一种 基于__new__的单例
# 通过使用__new__来控制实例的创建过程

# 实例化对象的的过程:1.先产生一个空对象(__new__),然后在调用init方法
class Singleton(object):
    __instance = None
    def __new__(cls,*args,**kwargs):
        if not cls.__instance:
            # 实际object.__new__(self)返回的就是一个对象
            cls.__instance = super(Singleton,cls).__new__(cls,*args,**kwargs)
        return cls.__instance

a1 = Singleton()
a2 = Singleton()
# 第二种:基于模块的单例模式(用来导入的时候) # 原因:第一次调用模块时,执行一遍,第二次以后调用都不执行(模块调用只执行一次) class Settings(object): x = 100 def foo(self): print("foo") settings = Settings() # 另一个py文件中调用这个模块 # from funcs import settings (这样内存中就有了settings对象,以后用的都是一个了,实现了单例) # 第三种 # 思路: 定义一个类(__instance = None),在类中定义一个类方法 singleton(cls),如果__instance为空,则创建对象 import settings class MySQL(object): __instance = None def __init__(self,ip,port): self.ip = ip self.port = port # 可以保证只有一个对象,但还是可以通过调用类产生新对象(解决:用元类来控制实例化的过程__call__) @classmethod def singleton(cls): if not cls.__instance: # 创建对象 obj = cls(settings.IP,settings.PORT) cls.__instance = obj return cls.__instance obj4=MySQL.singleton() obj5=MySQL.singleton() # id 相同 # 以上参数为配置文件中同一套参数,实现了单例

# 第四种方式,利用元类来实现单例 # 调用类产生对象,实际是调用原类中的__call__方法,自定义__call__方法 # 定义元类 class MyMeta(type): __instance = None # 控制类Foo的调用过程,即控制实例化Foo的过程 def __call__(self, *args, **kwargs): if not MyMeta.__instance: __instance = object.__new__(self) self.__init__(__instance,*args,**kwargs) MyMeta.__instance = __instance return MyMeta.__instance class Printer(metaclass = MyMeta): print(1111) p1 = Printer() p2 = Printer() # id 地址一样

 

实现单例的四种方法

原文:https://www.cnblogs.com/Afrafre/p/10384792.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!