シナリオ1、特定のサーバープログラムの構成情報がファイルに保存され、クライアントがAppConfigクラスを介して構成ファイル情報を読み取ります。プログラムの実行中に、構成ファイルのコンテンツを使用する必要がある場所が多数ある場合、つまり、AppConfigオブジェクトのインスタンスを作成する必要がある場所が多数ある場合、システム内にAppConfigの複数のインスタンスが作成され、
メモリが大幅に浪費されます。リソース、特に構成ファイルの内容が大きい場合。実際、AppConfigのようなクラスの場合、プログラムの実行中にインスタンスオブジェクトが1つだけ存在することを望んでいます。
/
/class Singleton:
#私有化 将类的对象私有化
__instance=None
#重写__new__ 开辟空间 要想对象不产生空间 我就在new中提前阻止他创建空间
def __new__(cls, *args, **kwargs):
print('-------我进new了---------')
if cls.__instance is None: #对象第一次调用类时 instance还是none 故先创建一个空间 ,当新对象再调用时 ,就会执行else方法了
print('---1')
cls.__instance=object.__new__(cls) #调用object的new方法 给一号对象创建一个新空间
return cls.__instance
else:
print('---2')
return cls.__instance #二号对象调用else,将老地址赋值给二号对象,因此二号对象和一号对象共同指向一个地址,所以单例模式的优势就体现出来了,同时只有一个类地址,而非单例模式的类每次被对象引用后都会创建一个地址
#return object.__new__() 阻止他创建空间就行
def __init__(self): #new方法中return的为cls.instance(这是个内存地址) 将cls.instance传给了self ,init中的self本来接收的就是地址
pass
s=Singleton()
s2=Singleton()
print(s)
print(s2,'\n')
结果为
-------我进new了---------
---1
-------我进new了---------
---2
<__main__.Singleton object at 0x00000271C866B9E8>
<__main__.Singleton object at 0x00000271C866B9E8>
ケース2新しいシングルトンモード
//
class Singleton:
#私有化 将类的对象私有化
__instance=None
name='类的name'
#重写__new__ 开辟空间 要想对象不产生空间 我就在new中提前阻止他创建空间
def __new__(cls, *args, **kwargs):
print('-------我进new了---------')
if cls.__instance is None: #对象第一次调用类时 instance还是none 故先创建一个空间 ,当新对象再调用时 ,就会执行else方法了
print('---1')
cls.__instance=object.__new__(cls) #调用object的new方法 给一号对象创建一个新空间
return cls.__instance
else:
print('---2')
return cls.__instance #二号对象调用else,将老地址赋值给二号对象,因此二号对象和一号对象共同指向一个地址,所以单例模式的优势就体现出来了,同时只有一个类地址,而非单例模式的类每次被对象引用后都会创建一个地址
#return object.__new__() 阻止他创建空间就行
def __init__(self): #new方法中return的为cls.instance(这是个内存地址) 将cls.instance传给了self ,init中的self本来接收的就是地址
pass
def show(self,n):
print('------------->show',Singleton.name,n)
s=Singleton()
s2=Singleton()
print(s)
print(s2)
print('---------------------------分割线-----------------------------')
s.show(5)
s2.show(7)
结果为
-------我进new了---------
---1
-------我进new了---------
---2
<__main__.Singleton object at 0x00000271C8671E48>
<__main__.Singleton object at 0x00000271C8671E48>
---------------------------分割线-----------------------------
------------->show 类的name 5
------------->show 类的name 7
シングルトンモードデコレータはラップデコレータを使用する必要があります。
以下はラップの概要です。デコレータ
の役割:元の機能コードを変更しないことに基づいて、ユーザー認証などの追加機能が追加されます。
@wraps(view_func)の役割:デコレータ(名前、ドキュメントなど)を使用して元の関数の構造を変更しません
1。@wrapsデコレータを使用しない場合は、__ name__と__doc__の出力を確認してください。
分析:test()メソッドを装飾する場合、実際にはtest = decorator(test)です。
#Returnedコール試験。ように、ラッパー・メソッドにテストポイントをさせ、あるラッパー法の基準となる名実際のラッパーである。名、
それが注釈されている場合メソッドの名前が後で発見された場合デコレータを取得させることができます埋め込み関数の名前とコメント。
2. @wrapsデコレータを使用して、この問題を解決します
//
def decorator(func):
"""this is decorator __doc__"""
def wrapper(*args, **kwargs):
"""this is wrapper __doc__"""
print("this is wrapper method")
return func(*args, **kwargs)
return wrapper
@decorator
def test():
"""this is test __doc__"""
print("this is test method")
print("__name__: ", test.__name__)
print("__doc__: ", test.__doc__)
"""
结果:
__name__: wrapper
__doc__: this is wrapper __doc__
"""
# 分析: 对test()方法进行装饰时候,实际上是 test = decorator(test)
# 返回的是wrapper方法的引用,也就是让test指向了wrapper方法,所以调用test.__name__, 实际上是wrapper.__name__,
# 这样子可能会造成后面查找该方法的名字已经注释时候会得到装饰器的内嵌函数的名字和注释。
# 2. 使用@wraps装饰器解决这个问题
from functools import wraps
def decorator(func):
"""this is decorator __doc__"""
@wraps(func) #使用@wraps装饰器解决这个问题
def wrapper(*args, **kwargs):
"""this is wrapper __doc__"""
print("this is wrapper method")
return func(*args, **kwargs)
return wrapper
@decorator
def test():
"""this is test __doc__"""
print("this is test method")
print("__name__: ", test.__name__)
print("__doc__: ", test.__doc__) #输出文件开头注释的内容
"""
结果:
__name__: test
__doc__: this is test __doc__
"""
#デコレータを使用してシングルトンモードを実装します。デコレータはdefまたはclassを変更できます
//
from functools import wraps
def Singleton(cls):
_instance={
}
@wraps(cls)
def _singleton(*args,**kwargs):
if cls not in _instance:
_instance[cls]=cls(*args,**kwargs) #典型的字典存储方式
return _instance[cls] #返回字典的values值
return _singleton
@Singleton
class Settings():
def __init__(self):
self.a='被修饰的方法'
self.b='xxxxx'
print(self.a)
s1=Settings()
s2=Settings()
print(s1,s2)
结果为
被修饰的方法
<__main__.Settings object at 0x000001E84DC71EF0> <__main__.Settings object at 0x000001E84DC71EF0>