python元類 與 單例模式

一:元類

# 元類,即函數type(clsName,bases,dict)

# 方式一:
# code = """
# country = 'China'      #局部名字
# def __init__(self,name,age):
#     self.name = name
#     self.age = age
# """
# class_dict = {}
# exec(code,{},class_dict)  #將字符串中的代碼產生的全局名字與值放入第二個參數裏,局部名字與值放入第三個參數裏
# Chinese = type('Chinese',(object,),class_dict)

# 方式二:
def __init__(self,name,age):
    self.name = name
    self.age = age
Chinese = type('Chinese',(),{'__init__':__init__,'country':'China'})

c1 = Chinese('rock',18)
print(c1.name,c1.age,c1.country)
# 定製元類,即定製函數type(clsName,bases,dict)

class MyMeta(type):   # 繼承自元類type,重寫__new__方法,從而控制類的屬性的創建
    def __new__(cls, cls_name,bases,dict):
        attrs = ((key,value) for key,value in dict.items())
        lower_attrs = ((key.lower(), value) for key,value in attrs)  #將屬性名全改爲小寫
        dict = {}
        for k,v in lower_attrs:
            # dict.setdefault(k,v)
            dict[k]=v
        # return type.__new__(cls,cls_name,bases,dict)
        return super().__new__(cls, cls_name,bases,dict)


class Foo(metaclass=MyMeta):
    Name = 'rock'
    # __metaclass__ = MyMeta    這是python2中的用法

f1 = Foo()
f2 = Foo()
print(f1.Name)   #'Foo' object has no attribute 'Name'
print(f2.name)    # rock

 

二:單例模式

       單例模式,也叫單子模式,是一種常用的軟件設計模式。在應用這個模式時,單例對象的類必須保證只有一個實例存在。許多時候整個系統只需要擁有一個的全局對象,這樣有利於我們協調系統整體的行爲。比如在某個服務器程序中,該服務器的配置信息存放在一個文件中,這些配置數據由一個單例對象統一讀取,然後服務進程中的其他對象再通過這個單例對象獲取這些配置信息。這種方式簡化了在複雜環境下的配置管理。

 

       實現單例模式方法小結:

# 方法一:使用模塊
# mysingleton.py
class Singleton:
    def foo(self):
        pass
singleton = Singleton()

# 需要使用時導入該單例
# other.py
from mysingleton import singleton
# 方法二:使用裝飾器

# 多線程下需要加鎖
# from threading import Lock

def singleton(cls):
    # instance_lock = Lock()
    instances = {}
    def wrapper(*args, **kwargs):
        if cls not in instances:
            # with instance_lock:
            #     if cls not in instances:
                    instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

@singleton
class Foo:
    pass

 

# 方法三:使用元類 類是由元類type實例化而來,實例化類時(調用類對象),觸發元類的__call__方法

class Singleton(type):
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls,'_instance'):
            cls._instance = super().__call__(*args, **kwargs)
        return cls._instance


class MyClass(metaclass=Singleton):
    pass

f1 = MyClass()
f2 = MyClass()
print(f1 is f2)  # True

 

# 方法四:使用類方法

# 支持多線程
from threading import Lock

class Singleton:
    _instance_lock = Lock()
    @classmethod
    def get_instance(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            with Singleton._instance_lock:
                # if not hasattr(cls, "_instance"):
                cls._instance = cls(*args, **kwargs)
        return cls._instance

class MyClass(Singleton):
    pass

 

# 方法五:重寫 __new__方法

from threading import Lock

class Singleton():
    _instance_lock = Lock()
    def __new__(cls,cls_name,bases,dict):
        if not hasattr(cls, '_instance'):  
            with Singleton._instance_lock:
                # if not hasattr(cls, '_instance'):
                cls._instance = super().__new__(cls,cls_name,bases,dict)
        return cls._instance

class MyClass(Singleton):
    pass

 

發佈了53 篇原創文章 · 獲贊 34 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章