单例的实现方式
admin
2023-07-11 20:05:04
0次
单例的实现方式:
1、基于类

#encoding=utf-8
class Singleton(object):

    def __init__(self):
        pass

    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance

s1 = Singleton.instance()
s2 = Singleton.instance()

print(s1 is s2)

支持多线程:
#encoding=utf-8
import threading

class Singleton(object):
    _instance_lock = threading.Lock()

    def __init__(self):
        pass

    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):#
            with Singleton._instance_lock:#枷锁
                if not hasattr(Singleton, "_instance"):
                    Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance

def task(arg):
    obj = Singleton.instance()
    print(obj)

for i in range(10):
    t = threading.Thread(target=task,args=(i,))
    t.start()

obj = Singleton.instance()
print(obj)

2、利用__new__()
#encoding=utf-8

class Singleton(object):

    def __init__(self):
        pass

    def __new__(cls,*args,**kwargs):
        if not hasattr(cls,"_instance"):
            cls._instance = object.__new__(cls)
        return cls._instance

p1 = Singleton()
p2 = Singleton()
print(p1 is p2)

支持多线程方式

#encoding=utf-8
import threading

class Singleton(object):

    _instance_lock = threading.Lock()

    def __init__(self):
        pass

    def __new__(cls,*args,**kwargs):
        if not hasattr(cls,"_instance"):
            with cls._instance_lock:
                if not hasattr(cls,"_instance"):
                    cls._instance = object.__new__(cls)
        return cls._instance

def task():
    obj = Singleton()
    print(obj)

for i in range(20):
    t = threading.Thread(target=task,args=())
    t.start()

3、利用装饰器
#encoding=utf-8
import threading

def Singleton(cls):

    _instance = {}

    def _singleton(*args,**kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args,**kwargs)
        return _instance[cls]

    return _singleton

@Singleton
class Person(object):#Person = Singleton(Person)
    a =  10

    def __init__(self,x=0):
        self.x = x

p = Person(2)#_singleton(2)
p2 = Person(3)

print(p is p2)

print(p.x)
print(p2.x)

示例1:
#encoding=utf-8
class Person(object):
    __instance = None#定义一个类变量,用于绑定实例对象
    def __init__(self,name,age):
        self.name = name
        self.age = age

    @classmethod
    def get_instance(cls,name,age):
        if cls.__instance == None:
            cls.__instance =Person(name,age)
        return cls.__instance

    def get_info(self):
        return self.name + ":" + str(self.age)

p1 = Person.get_instance("xxx",20)

p2 = Person.get_instance("yyy",50)

print(p1 is p2)

print(p1.get_info())
print(p2.get_info())

#此种实现方式无法在生成实例后改变实例变量的值

示例2:
#encoding=utf-8
class Singleton(object):
    _instance = None

    def __new__(cls,a,b,*args,**kwargs):
        if cls._instance == None:
            cls._instance = super(Singleton,cls).__new__(cls,*args,**kwargs)
        return cls._instance

class Person(Singleton):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def getInfo(self):
        return "姓名: %s,年龄: %s" %(self.name,self.age)

p1 = Person("张三",20)
print(p1.getInfo())

p2 = Person("李四",20)
print(p1.getInfo())

print(p1 is p2)

print("类变量: ",Person._instance)

示例3:
#encoding=utf-8

class Person(object):

    __instance = None#创建一个类变量用户存储类的实例对象

    def __init__(self,name,age):

        self.name = name
        self.age = age

    def __new__(cls,name,age):#自定义Person自己的__new__()方法用于产生实例对象,此处需要传入name,age两个参数
        if cls.__instance == None:#保证实例对象__instance只会被赋值一次,如果之前已经创建过实例,直接返回之前创建的实例
            #cls.__instance = super(Person,cls).__new__(cls)
            cls.__instance = object.__new__(cls)#调用父类的__new__方法创建对象

        return cls.__instance#返回实例对象

    def getInfo(self):

        return "姓名: %s,年龄: %s" %(self.name,self.age)

p1 = Person("h",20)
print(p1.getInfo())

p2 = Person("kkk",30)
print(p1.getInfo())
print(p2.getInfo())

print(p1 is p2)

'''
以上代码执行过程:
p1 = Person("h",20)
首先调用__new__方法产生实例p1,此时Person的__instance为none所以会创建一个对象,
然后调用__init__方法,把返回的实例对象__instance传入self中,并初始实例变量name,age

print(p2.getInfo())
首先调用__new__方法产生实例p2,此时Person的__instance为不为None,为p1,所以会直接返回对象p1,
然后调用__init__方法,把返回的实例对象__instance传入self中,并用新的name,age初始实例变量name,age 
'''    

如果__init__有其他参数,__new__需要传入参数

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...