zoukankan      html  css  js  c++  java
  • 单例模式

    使用new方法实现单例模式

      每个实例的创建是通过__new__方法,所以如果要实现一个类只能有一个实例就得重写__new__函数。

    class A:
        _instance = None
        def __new__(cls, *args, **kwargs):
            if not cls._instance:
                print("创建了一个实例")
                obj = super().__new__(cls, *args, **kwargs)
                cls._instance = obj
                return obj
            return cls._instance
    
        def __init__(self):
            print('开始初始化')

    执行:

    a = A()

    输出为:

    创建了一个实例
    开始初始化

    执行:

    b = A()

    输出为:

    开始初始化

    执行:

    print(id(a), id(b))  # 每个实例的id一样

    输出:

    140078083206056 140078083206056

    使用共享属性实现单例模式

      与上一种方法不同的是,此种方法当执行__new__方法后,每次生成一个新的实例。只不过每个实例共享同样的属性,因此实际使用的效果和上面的方法一样。但严格意义上讲,我认为这不算单例。

    class A:
        _myDict = {}
        def __new__(cls, *args, **kwargs):
            obj = super().__new__(cls, *args, **kwargs)
            obj.__dict__ = cls._myDict
            print("创建了一个实例")
            return obj
        
        def __init__(self):
            print("开始初始化")

    执行:

    a = A()

    输出为:

    创建了一个实例
    开始初始化

    执行:

    b = A()

    输出为:

    创建了一个实例
    开始初始化

    执行:

    print(id(a), id(b))  # 每个实例的id不一样

    输出为:

    140078082716952 140078082716504

    执行:

    a.a = '1'  # 此时对实例a添加一个a属性
    
    pirnt(b.a)  # 通过b得到了与a一模一样的值

    使用装饰器实现单例模式

      装饰器的特色就是给函数添加额外的功能,同样可以在类上使用装饰器,来限制实例的个数。但此种方法与上两种不同的是,前两种类的__init__方法在生成实例后都被执行了执行了一次,而此种方法只有在第一次生成实例时才调用__init__方法。

    def oneObject(cls):
        def wrap(*args, **kwargs):
            if not hasattr(cls, '_instance'):
                obj = cls(*args, **kwargs)
                cls._instance = obj
                return obj
            return cls._instance
        return wrap
    
    
    
    @ oneObject
    class A:
        def __init__(self):
            print("已经创建了一个实例")

    执行:

    a = A()

    输出为:

    已经创建了一个实例

    执行:

    b = A()  # 注意,没有执行__init__函数

    print(id(a), id(b))

    输出为:

    140357050460928 140357050460928
     
  • 相关阅读:
    Docker的安装和scrapy-splash的安装
    scrapyd打包到服务器运行
    一些python的简单有用方法
    NFS学习
    apache配置https加密传输
    httpd基于域名不同的虚拟主机配置
    Openssl创建私有CA
    NODEJS版本控制和切换
    HyperV使用Centos系统安装FTP服务
    装Anaconda报错This Python interpreter is in a conda environment, but the environment has not been activated. Libraries may fail to load. To activate this environment please see http://conda.io/activation
  • 原文地址:https://www.cnblogs.com/zhouyang123200/p/6538305.html
Copyright © 2011-2022 走看看