python 单例模式


前置知识、反射

概念:它可以把字符串映射到实例的变量或者实例的方法然后可以去执行调用、修改等操作

方法:

  • getattr 获取指定字符串名称的对象属性
  • setattr 为对象设置一个对象
  • hasattr 判断对象是否有对应的对象(字符串)
  • delattr 删除指定属性

一、单例模式

单例模式在python中存在广泛,例如模块就是一个经典的单例模式,使用模块可以实现单例模式,这是一种单例模式实现方法,另外的方法还有使用装饰器实现,使用类与反射实现,以及重写__new__实现

1、使用装饰器实现单例模式

from multiprocessing import Lock

def SingleInstance(cls):
    cls.__lock__ = Lock()
    def new(cls,*args,**kwargs):
        cls.__lock__.acquire()
        try:
            if not  hasattr(cls,'instance'):
                cls.instance= object.__new__(cls)
            return cls.instance
        finally:
            cls.__lock__.release()
    cls.__new__=new
    return cls

@SingleInstance
class people():
    def __init__(self,name,age):
        self.name = name
     self.age = age    

2、使用类实现单例模式

class SingleInstance:
    def __init__(self,lock=None):
        self.lock=lock or Lock()

    def __call__(self,cls):
        def new(cls, *args, **kwargs):
            self.lock.acquire()
            try:
                if not hasattr(cls, 'instance'):
                    cls.instance = object.__new__(cls)
                return cls.instance
            finally:
                self.lock.release()
        cls.__new__ = new
        return cls
@SingleInstance
class people():
    def __init__(self,name,age)
    self.name = name
    self.age = age

3、使用__new__实现单例模式

#例子为办公室人员共用同一台打印机的模式
class Manager:
    # 使用打印机上传要打印的信息
    def use_painter(self, info, pr):
        pr.add_task(info)

class Staff:
    # 使用打印机上传要打印的信息
    def use_painter(self, info, pr):
        pr.add_task(info)

class Potiner:
#创建一个打印机类,并用两个类变量来控制 __new__和__init__方法
    __stance = None
    __is_init = False
#重写一个__new__方法,并创建一个单例模式
    def __new__(cls, *args, **kwargs):
        if cls.__stance is None:
           cls.__stance = object.__new__(cls)
        return cls.__stance

#让程序调用时只初始化一次self.get_list
    def __init__(self):
        if Potiner.__is_init is False:
            print("-----------")
            self.get_list = []
            Potiner.__is_init = True
#打印方法
    def add_task(self, info):
        # Potiner.list_print(info)
        self.get_list.append(info)
#打印数据
    def get_print(self):
        print(self.get_list)

# A员工
pr1 = Potiner()
m1 = Manager()
m1.use_painter("hello", pr1)

# B员工
pr2 = Potiner()
str1 = Staff()
str1.use_painter("python", pr2)
# C员工
pr = Potiner()
pr.get_print()

print(id(pr1))
print(id(pr2))
print(id(pr))
posted @ 2020-08-12 17:07  inhocho  阅读(19)  评论(0)    收藏  举报