zoukankan      html  css  js  c++  java
  • python的单例模式和__new__方法

    单例模式是一个常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。比如说:利用加标签的白名单防止跨站脚本攻击XXS创建一个XxsFile类,不同的人访问都要创建XxsFile对象的实例,这就导致系统中存在多个XxsFile的实例对象,而这样会严重浪费内存资源。事实上类似于XxsFile这样的类,我们希望在程序运行期间只存在一个实例对象,在python中,我们可以使用单例。如下列几种方法:


    在Python中new方法和init方法类似,但是如果两个都存在那么new先执行

    __new__(cls, *args, **kwargs)

    __new__()中的需要传递一个参数cls,cls表示需要实例化的类,此参数在实例化时由Python解析器自动提供

    1、类方法classmethod

    # -*-coding:utf-8 -*-
    class Foo(object):
        __instance = None
    
        @classmethod
        def instance(self):
            if self.__instance:
                return self.__instance
    
            else:
                obj = self()
                self.__instance = obj
                return self.__instance
    obj1=Foo.instance()
    obj2=Foo.instance()
    print(obj1,obj2)
    

    2、基于__new__方法实现(推荐使用、方便)

    当我们实例化一个对象时,是先执行了类的__new__方法(当我们没写时,默认调用object.__new__),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所以我们可以基于这个,实现单例模式:

    # -*-coding:utf-8 -*-
    class Foo(object):
        __instance=None
        def __init__(self):
            pass
        def __new__(cls, *args, **kwargs):
    
            if cls.__instance:
                return cls.__instance
            else:
                obj = object.__new__(cls,*args,**kwargs)
                cls.__instance = obj
                return cls.__instance
    obj1=Foo()
    obj2=Foo()
    print(obj1,obj2)
    

    Python new()方法,为对象分配内存,返回对象的引用

    # -*-coding:utf-8 -*-
    class MusicPlayer(object):
    
        #为对象分配内存空间
        def __new__(cls, *args, **kwargs):
    
            #1、创建对象时,new方法会被自动调用
            print("创建对象,分配内存空间")
    
            #2、为对象分配空间
            instance = super().__new__(cls)
    
            #3、返回对象引用
            return instance
        #对象初始化,定义实例属性
        def __init__(self):
            print("播放器初始化")
    
    #创建播放器对象
    player = MusicPlayer()
    print(player)
    

    __new__方法:

    使用MusicPlayer()创建对象时,python的解释器首先会调用__new__方法为对象分配空间,如果不分配空间那么就不会调用初始化__init____new__是一个由object基类提供的内置的静态方法,主要作用有两个:

    1、在内存空间中为对象分配空间

    2、返回对象的引用

    Python的解释器获取得到对象的引用后,将引用作为第一个参数,传递给__init__,

    1、重写__new__方法python用return super().__new__(cls),否则Python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法,注意:__new__是一个静态方法,在调用时需要主动传递cls参数

    如果分配了内存空间,就会调用初始化__init__的结果:

    # -*-coding:utf-8 -*-
    class MusicPlayer(object):
    
        #为对象分配内存空间
        def __new__(cls, *args, **kwargs):
    
            #1、创建对象时,new方法会被自动调用
            print("创建对象,分配内存空间")
    
            #2、为对象分配空间
            instance = super().__new__(cls)
    
            #3、返回对象引用
            return instance
        #对象初始化,定义实例属性
        def __init__(self):
            print("播放器初始化")
    
    #创建播放器对象
    player = MusicPlayer()
    print(player)
    
    #输出:
        # 创建对象,分配内存空间
        # 播放器初始化
        # <__main__.MusicPlayer object at 0x033D09B0>
    

    如果__new__不分配内存空间,创建对象的时候就不会去的调用__init__,结果如下:

        # -*-coding:utf-8 -*-
    class MusicPlayer(object):
    
        #为对象分配内存空间
        def __new__(cls, *args, **kwargs):
    
            #1、创建对象时,new方法会被自动调用
            print("创建对象,分配内存空间")
    
            
        #对象初始化,定义实例属性
        def __init__(self):
            print("播放器初始化")
    
    #创建播放器对象
    player = MusicPlayer()
    print(player)
    
    #输出:
        #创建对象,分配内存空间
        #None
    
  • 相关阅读:
    AngularJS 拦截器
    android的Log日志打印管理工具类(一)
    android的Home键的监听封装工具类(一)
    android开发SDcard 响应的文件相关处理(一)
    android开发时间和日期的代码实现工具类(一)
    android文件和图片的处理工具类(一)
    android的二进制和十六进制的相互转换工具类(一):
    android的color整理(一)
    android经典Demo(转载)
    Android 根据EditText搜索框ListView动态显示数据
  • 原文地址:https://www.cnblogs.com/venvive/p/11530684.html
Copyright © 2011-2022 走看看