單例的實現方式

單例的實現方式: 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__需要傳入參數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章