1. 程式人生 > 實用技巧 >python 反射與單例模式

python 反射與單例模式

反射

  • 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))