一:元類
# 元類,即函數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