python 反射與單例模式
阿新 • • 發佈:2020-08-04
反射
- getattr 獲取指定字串名稱的物件屬性
- setattr 為物件設定一個物件
- hasattr判斷物件是否有對應的物件(字串)
- delattr 刪除指定屬性
執行緒鎖
單例模式
單例模式在python中存在廣泛,例如模組就是一個經典的單例模式,使用模組可以實現單例模式,這是一種單例模式實現方法,另外的方法還有使用裝飾器實現,使用類與反射實現,以及重寫__new__實現
使用裝飾器實現單例模式
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
使用類實現單例模式
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
使用__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))