• 单例模式


      单例模式是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在,当你希望在整个系统中,某个类只出现一个实例时,单例对象就能排上用场

      在python中,我们可以用多种方法来实现单例模式:使用模块、使用__new__、使用装饰器、使用元类(metaclass),共享属性。

    使用模块

      其实python的模块就是纯天然的单例模式,因为模块在第一次导入时,会生成.pyc文件,当第二次导入时,就会直接加载.pyc文件,而不会再次执行模块代码。因为,我们只需要把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以考虑这样做 

    # singleTon.py
    class Animal(object):
        def eat(self):
            print('eating...')
    
    a=Animal()

      将上面的代码保存在文件singleTon.py中,然后这样使用:

    # my_funcs.py
    from singleTon import a
    a.eat()

    使用__new__

      为了使类只能出现一个实例,我们使用__new__来控制实例的创建过程

    # 单例模式基于__new__
    class Animal(object):
        _instance=None
    
        def __new__(cls,*args,**kw):
            if not cls._instance:
                cls._instance=super(Animal,cls).__new__(cls,*args,**kw) #构建一个实例对象
    
            return cls._instance
    
    # 测试
    dog=Animal()
    cat=Animal()
    
    print(id(dog))
    print(id(cat))

      在上面的代码中,我们将类的实例和一个类变量_instance关联起来,如果cls._instance为None则创建实例,否则直接返回cls._instance

    使用装饰器

      装饰器可以动态的修改一个类或函数的功能。这里我们可以使用装饰器来装饰某个类,使其只能生成一个实例

    # 单例模式基于装饰器
    from functools import wraps
    
    def singleton(cls):
        instances={}
    
        @wraps(cls)
        def getinstance(*args,**kwargs):
            if cls not in instances:
                instances[cls]=cls(*args,**kwargs)
            return instances[cls]
    
        return getinstance
    
    @singleton
    class Animal(object):
        def eat(self):
            print('eating...')

    使用metaclass

      元类可以控制类的创建过程,它主要完成拦截类的创建、修改类的定义,然后返回修改后的类

    # 单例模式基于元类
    
    class Singleton(type):
        _instance={}
    
        def __call__(cls,*args,**kwargs):
            if cls not in cls._instance:
                cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
    
            return cls._instance[cls]
    
    class Myclass(metaclass=Singleton):    
        pass

    共享属性

      创建实例时把所有实例的__dict__指向同一个字典,这样它们具有相同的属性和方法

    class Singleton(object):
    
        _state = {}
    
        def __new__(cls, *args, **kwargs):
            obj = super(Singleton,cls).__new__(cls)
            obj.__dict__ = cls._state
            return obj
    
    class Myclass(Singleton):
        pass
  • 相关阅读:
    Postgres窗口函数学习
    关于KMP算法
    Kettle应用实例
    mybatis中po类继承另一个po类时查不出另一个po类里的属性
    查看Mybatis动态SQL
    取每个班前5名成绩的sql
    scatter/gather与map/reduce技术的布道推广从换个说法开始
    神奇的O記
    【坑】软件的大版本的各类小版本支持问题
    oracle时间处理tochar的黑幕坑
  • 原文地址:https://www.cnblogs.com/iamluoli/p/9165928.html
Copyright © 2020-2023  润新知